mirror of https://github.com/tiangolo/fastapi.git
Merge 0f7863627d into 5b28a04d55
This commit is contained in:
commit
e69b113210
|
|
@ -107,3 +107,41 @@ You can also set the `route_class` parameter of an `APIRouter`:
|
|||
In this example, the *path operations* under the `router` will use the custom `TimedRoute` class, and will have an extra `X-Response-Time` header in the response with the time it took to generate the response:
|
||||
|
||||
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *}
|
||||
|
||||
## Experimental: HTTP QUERY method { #experimental-http-query-method }
|
||||
|
||||
/// warning
|
||||
|
||||
This is an experimental feature for the non-standard HTTP QUERY method. Use with caution.
|
||||
|
||||
///
|
||||
|
||||
FastAPI and `APIRouter` expose a `.query()` decorator for the experimental HTTP QUERY method, as defined in the <a href="https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-02.html" class="external-link" target="_blank">IETF draft for "safe method with body"</a>.
|
||||
|
||||
The QUERY method works at runtime and can be used like any other HTTP method decorator:
|
||||
|
||||
```python
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
class SearchQuery(BaseModel):
|
||||
text: str
|
||||
limit: int = 10
|
||||
|
||||
@app.query("/search")
|
||||
def search_items(query: SearchQuery):
|
||||
return {"results": f"Searching for: {query.text}"}
|
||||
```
|
||||
|
||||
### Limitations { #query-method-limitations }
|
||||
|
||||
* **Not shown in interactive docs**: The QUERY method will not appear in the OpenAPI schema or interactive documentation (Swagger UI, ReDoc) because the OpenAPI specification does not define "query" operations.
|
||||
* **Limited client support**: Not all HTTP clients and proxies support the QUERY method.
|
||||
|
||||
/// tip
|
||||
|
||||
For maximum interoperability, prefer using **POST** for operations that require a request body. The QUERY method is only useful in specialized scenarios where you need to follow the IETF draft specification.
|
||||
|
||||
///
|
||||
|
|
|
|||
|
|
@ -107,3 +107,41 @@ También puedes establecer el parámetro `route_class` de un `APIRouter`:
|
|||
En este ejemplo, las *path operations* bajo el `router` usarán la clase personalizada `TimedRoute`, y tendrán un header `X-Response-Time` extra en el response con el tiempo que tomó generar el response:
|
||||
|
||||
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *}
|
||||
|
||||
## Experimental: Método HTTP QUERY { #experimental-http-query-method }
|
||||
|
||||
/// warning | Advertencia
|
||||
|
||||
Esta es una funcionalidad experimental para el método HTTP QUERY no estándar. Úsalo con precaución.
|
||||
|
||||
///
|
||||
|
||||
FastAPI y `APIRouter` exponen un decorador `.query()` para el método HTTP QUERY experimental, tal como se define en el <a href="https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-02.html" class="external-link" target="_blank">borrador del IETF para "método seguro con cuerpo"</a>.
|
||||
|
||||
El método QUERY funciona en tiempo de ejecución y puede usarse como cualquier otro decorador de método HTTP:
|
||||
|
||||
```python
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
class SearchQuery(BaseModel):
|
||||
text: str
|
||||
limit: int = 10
|
||||
|
||||
@app.query("/search")
|
||||
def search_items(query: SearchQuery):
|
||||
return {"results": f"Searching for: {query.text}"}
|
||||
```
|
||||
|
||||
### Limitaciones { #query-method-limitations }
|
||||
|
||||
* **No se muestra en la documentación interactiva**: El método QUERY no aparecerá en el esquema OpenAPI ni en la documentación interactiva (Swagger UI, ReDoc) porque la especificación OpenAPI no define operaciones "query".
|
||||
* **Soporte limitado de clientes**: No todos los clientes HTTP y proxies soportan el método QUERY.
|
||||
|
||||
/// tip | Consejo
|
||||
|
||||
Para máxima interoperabilidad, prefiere usar **POST** para operaciones que requieren un cuerpo de request. El método QUERY solo es útil en escenarios especializados donde necesitas seguir la especificación del borrador del IETF.
|
||||
|
||||
///
|
||||
|
|
|
|||
|
|
@ -4541,6 +4541,17 @@ class FastAPI(Starlette):
|
|||
generate_unique_id_function=generate_unique_id_function,
|
||||
)
|
||||
|
||||
def query(
|
||||
self,
|
||||
path: str,
|
||||
*args: Any,
|
||||
**kwargs: Any,
|
||||
) -> Callable[[DecoratedCallable], DecoratedCallable]:
|
||||
"""
|
||||
Experimental: HTTP QUERY method. See APIRouter.query for caveats.
|
||||
"""
|
||||
return self.router.query(path, *args, **kwargs)
|
||||
|
||||
def websocket_route(
|
||||
self, path: str, name: Union[str, None] = None
|
||||
) -> Callable[[DecoratedCallable], DecoratedCallable]:
|
||||
|
|
|
|||
|
|
@ -4538,6 +4538,66 @@ class APIRouter(routing.Router):
|
|||
generate_unique_id_function=generate_unique_id_function,
|
||||
)
|
||||
|
||||
def query(
|
||||
self,
|
||||
path: str,
|
||||
*,
|
||||
response_model: Any = Default(None),
|
||||
status_code: Optional[int] = None,
|
||||
tags: Optional[List[Union[str, Enum]]] = None,
|
||||
dependencies: Optional[Sequence[params.Depends]] = None,
|
||||
summary: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
response_description: str = "Successful Response",
|
||||
responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
|
||||
deprecated: Optional[bool] = None,
|
||||
operation_id: Optional[str] = None,
|
||||
response_model_include: Optional[IncEx] = None,
|
||||
response_model_exclude: Optional[IncEx] = None,
|
||||
response_model_by_alias: bool = True,
|
||||
response_model_exclude_unset: bool = False,
|
||||
response_model_exclude_defaults: bool = False,
|
||||
response_model_exclude_none: bool = False,
|
||||
include_in_schema: bool = False,
|
||||
response_class: Type[Response] = Default(JSONResponse),
|
||||
name: Optional[str] = None,
|
||||
callbacks: Optional[List[BaseRoute]] = None,
|
||||
openapi_extra: Optional[Dict[str, Any]] = None,
|
||||
generate_unique_id_function: Callable[[APIRoute], str] = Default(
|
||||
generate_unique_id
|
||||
),
|
||||
) -> Callable[[DecoratedCallable], DecoratedCallable]:
|
||||
"""
|
||||
Experimental: register a handler for the non-standard HTTP QUERY method.
|
||||
Works at runtime, but not represented in OpenAPI (spec doesn't support it).
|
||||
"""
|
||||
return self.api_route(
|
||||
path=path,
|
||||
response_model=response_model,
|
||||
status_code=status_code,
|
||||
tags=tags,
|
||||
dependencies=dependencies,
|
||||
summary=summary,
|
||||
description=description,
|
||||
response_description=response_description,
|
||||
responses=responses,
|
||||
deprecated=deprecated,
|
||||
methods=["QUERY"],
|
||||
operation_id=operation_id,
|
||||
response_model_include=response_model_include,
|
||||
response_model_exclude=response_model_exclude,
|
||||
response_model_by_alias=response_model_by_alias,
|
||||
response_model_exclude_unset=response_model_exclude_unset,
|
||||
response_model_exclude_defaults=response_model_exclude_defaults,
|
||||
response_model_exclude_none=response_model_exclude_none,
|
||||
include_in_schema=include_in_schema,
|
||||
response_class=response_class,
|
||||
name=name,
|
||||
callbacks=callbacks,
|
||||
openapi_extra=openapi_extra,
|
||||
generate_unique_id_function=generate_unique_id_function,
|
||||
)
|
||||
|
||||
@deprecated(
|
||||
"""
|
||||
on_event is deprecated, use lifespan event handlers instead.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class Payload(BaseModel):
|
||||
x: int
|
||||
|
||||
|
||||
def test_query_route_executes_and_openapi_survives():
|
||||
app = FastAPI()
|
||||
|
||||
@app.query("/items")
|
||||
def query_items(payload: Payload):
|
||||
return {"ok": payload.x}
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
# Runtime: the route is callable with QUERY
|
||||
r = client.request("QUERY", "/items", json={"x": 42})
|
||||
assert r.status_code == 200
|
||||
assert r.json() == {"ok": 42}
|
||||
|
||||
# OpenAPI: does not include the query route (excluded by default), and must not error
|
||||
schema = app.openapi()
|
||||
# The path is excluded from OpenAPI because include_in_schema=False by default
|
||||
assert "/items" not in schema["paths"]
|
||||
Loading…
Reference in New Issue