Fastapi alias for url/router/endpoint (set same handler for them)

Viewed 1183

How I can make alias (call the same handler) for similar url/routers like https://myapi/users/5 and https://myapi/users/me (my id placed in token and it's 5).

@router.get("/{employee_id}}", status_code=200, response_model=schemas.EmployeeOut)
async def get_employee(
        employee_id: int = Path(default=..., ge=0, description='Id получаемого сотрудника.', example=8),
        token: str = Depends(config.oauth2_scheme),
        postgres_session: AsyncSession = Depends(database.get_db)):
    try:
        token_payload = services.get_token_payload(token=token)
        if token_payload['role'] in (config.OPERATOR_ROLE, config.OPERATOR_ROLE, config.CLINIC_ROLE):
            return (await postgres_session.execute(statement=models.employees.select().where(
                models.employees.c.id == employee_id))).fetchone()
        else:
            raise config.known_errors['forbidden']
    except Exception as error:
        services.error_handler(error)

# Just as example!
@router.get("/me}", status_code=200, response_model=List[schemas.TicketOut])
async def get_me(
        token: str = Depends(config.oauth2_scheme)):
    token_payload = services.get_token_payload(token=token)
    get_employee(employee_id=token_payload['sub'])

These functions is almost identical, the one difference is that in the second function no path parameter employee_id, but it's anyway are present in the token.

You can wonder why you need me url - it's just for convenience

2 Answers

It is possible. You can specify multiple decorators with API path specifications. If you look closely at, say, router.post implementation, you will see, that decorator returns not wrapped function, but the original function, so you can pass it to another decorator safely.

Smth like this:

@router.post('/api/action1')
@router.post('/api/action2')
def do_action():
  pass
Related