Architecture
Every API request goes to one presenter, Tomaj\NetteApi\Presenters\ApiPresenter. It asks ApiDecider which endpoint matches, runs the checks in a fixed order and returns what the handler or the error handler produced.
The parts
| Part | Class or interface | Job |
|---|---|---|
| Presenter | ApiPresenter | Runs every step below. It is final. |
| Endpoint list | ApiDecider | addApi() registers endpoints, getApi() finds the one for a request. |
| Endpoint | EndpointIdentifier | Method, version, package and optional action. |
| Handler | ApiHandlerInterface, usually BaseHandler | Declares params and outputs, does the work. |
| Authorization | ApiAuthorizationInterface | Says whether the request may run. |
| Rate limit | RateLimitInterface | Optional, per endpoint. |
| Errors | ErrorHandlerInterface, DefaultErrorHandler | Turns failures into JSON responses. |
| Output checks | ConfiguratorInterface | Decides whether outputs are validated and error details shown. |
| Logger | ApiLoggerInterface | Optional, found in the DI container. |
The order of the steps
In short: CORS headers, endpoint lookup (404), rate limit (429), params are read, authorization (401), param errors (400), the handler, the output check (500) and logging. Params are read before authorization, but their errors are reported only after it, so a caller without access gets 401 and no details about the params.
The full order, with the code and the exit of every step, is on one page: ApiPresenter pipeline.
Not every response is logged
The rate limit, authorization and param error steps return early, so 429, 401, 400 and the 500 of a failing authorization never reach the logger in 3.x. 404, handler responses and handler or output errors are logged.
FAQ
Can I replace ApiPresenter with my own presenter?
Not by extending it, the class is final. You can configure it (setCorsHeader()) and swap its dependencies: the error handler, the configurator and the logger. See Error handling.
Why does a request with a wrong token and wrong params answer 401, not 400?
Authorization runs before param errors are reported. See step 6 above and Authorization.
Is the handler created for every endpoint on every request?
No. When you pass a class name to addApi(), the handler is taken from the DI container only when its endpoint is called. See Handlers.
What does the response of an unknown endpoint look like?
404 with {"status":"error","message":"Unknown api endpoint"}. The hello world example tests it.
Where do I see all the classes in one list?
In the Reference.