Skip to content

Commit 7bde082

Browse files
committed
Update README
1 parent 1afd354 commit 7bde082

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed

README.md

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,12 +332,49 @@ Here are some notable differences between building your REST API with pure FastA
332332
- REST-RPC only supports Body parameters for `PATCH`, `PUT`, and `POST`, not for `GET` and `DELETE`. Furthermore, only one Body parameter is supported, and FastAPI's `Body(embed=True)` is not supported.
333333
- Out of FastAPI's [Request Parameters](https://fastapi.tiangolo.com/reference/parameters/), REST-RPC only supports `Path`, `Query`, `Body`, and `Header`, not `Cookie`, `Form`, or `File`.
334334

335-
Other restrictions are:
336-
- In the API implementation, you don't need to add any annotations or default values to the router handlers. So usually, the only things that strictly have to match are the names of the route handler functions and their parameters. However, if you _decide_ to add annotations or default values, they _do_ have to match. Personal recommendation: Keep it simple in the prototyping phase since things are likely to be changed around and you'll be annoyed by changing the signatures in two places instead of one. Once the API definition becomes stable, you can still add the annotations to the API implementation to improve expressivity.
335+
Another important note: In the API implementation, you don't need to add any annotations or default values to the route handlers. So usually, the only things that strictly have to match are the names of the route handler functions and their parameters. So this is okay:
336+
337+
```python
338+
@api_def.get("/foo")
339+
def foo(bar: int = 42) -> dict[str, Any]: ...
340+
341+
# [...]
342+
343+
@api_impl.handler
344+
def foo(bar):
345+
return {"foo": bar}
346+
```
347+
348+
However, if you _decide_ to add annotations or default values, they _do_ have to match exactly, so these are all okay:
349+
350+
```python
351+
@api_impl.handler
352+
def foo(bar: int):
353+
return {"foo": bar}
354+
355+
@api_impl.handler
356+
def foo(bar: int = 42):
357+
return {"foo": bar}
358+
```
359+
360+
But these are not:
361+
362+
```python
363+
@api_impl.handler
364+
def foo(bar: float):
365+
return {"foo": bar}
366+
367+
@api_impl.handler
368+
def foo(bar = 0):
369+
return {"foo": bar}
370+
```
371+
372+
> [!TIP]
373+
> Personal recommendation: Keep it simple in the prototyping phase since things are likely to be changed around and you'll be annoyed by changing the signatures in two places instead of one. Once the API definition becomes stable, you can still add the annotations to the API implementation to improve expressivity.
337374
338375
## Performance Comparison
339376

340-
The [`benchmark`](directory) contains a very simple benchmarking script, where we compare the performance of the different engines on a simple `get("/")` without parameters. Your mileage may vary in other situations.
377+
The [`benchmark`](benchmark) directory contains a very simple benchmarking script, where we compare the performance of the different engines on a simple `get("/")` without parameters. Your mileage may vary in other situations.
341378

342379
As you can see below, `httpx` performs noticeably worse in this specific benchmark.
343380

@@ -349,4 +386,5 @@ So it's probably a good idea to use `requests` or `urllib3` if you want synchron
349386

350387
- Support for authentication. At the moment, you can only do this via middlewares in the backend implementation.
351388
- Support parameters in `ApiImplementation.make_fastapi()` that are forwarded to the `FastAPI()` constructor.
389+
- Make argument annotation matching more lax (e.g. when we annotate `Annotated[int, Path()]` in the definition, it should be okay to just annotate `int` in the handler).
352390
- Missing something? Create an issue.

0 commit comments

Comments
 (0)