Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions docs/book/v7/openapi/write-documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Defines a `DELETE` HTTP request.
It should specify at least the following parameters:

- `path`: the route to the resource (example: `/resource/{id}` - where `id` is a path parameter defined below)
- `operationId`: a name unique across the whole document, derived from the handler class name without the `Handler` suffix, with a lowercase first letter (example: `deleteUserResource`). Clients generated from the specification use it as the method name, so do not rename it once released
- `description`: verbose description of the endpoint's purpose
- `summary`: short description of the endpoint's purpose
- `security`: an array of security scheme(s) to be used—omit if the endpoint is not protected
Expand All @@ -52,6 +53,7 @@ Defines a `GET` HTTP request.
It should specify at least the following parameters:

- `path`: the route to a single or collection of resources (example: `/resource/{id}` for a single resource or `/resource` for a collection of resources)
- `operationId`: a name unique across the whole document, derived from the handler class name without the `Handler` suffix, with a lowercase first letter (example: `getUserCollection`). Clients generated from the specification use it as the method name, so do not rename it once released
- `description`: verbose description of the endpoint's purpose
- `summary`: short description of the endpoint's purpose
- `security`: an array of security scheme(s) to be used—omit if the endpoint is not protected
Expand All @@ -65,6 +67,7 @@ Defines a `PATCH` HTTP request.
It should specify at least the following parameters:

- `path`: the route to the resource (example: `/resource/{id}` - where `id` is a path parameter defined below)
- `operationId`: a name unique across the whole document, derived from the handler class name without the `Handler` suffix, with a lowercase first letter (example: `patchUserResource`). Clients generated from the specification use it as the method name, so do not rename it once released
- `description`: verbose description of the endpoint's purpose
- `summary`: short description of the endpoint's purpose
- `security`: an array of security scheme(s) to be used—omit if the endpoint is not protected
Expand All @@ -79,6 +82,7 @@ Defines a `POST` HTTP request.
It should specify at least the following parameters:

- `path`: the route to the resource (example: `/resource/{id}` - where `id` is a path parameter defined below)
- `operationId`: a name unique across the whole document, derived from the handler class name without the `Handler` suffix, with a lowercase first letter (example: `postUserResource`). Clients generated from the specification use it as the method name, so do not rename it once released
- `description`: verbose description of the endpoint's purpose
- `summary`: short description of the endpoint's purpose
- `security`: an array of security scheme(s) to be used—omit if the endpoint is not protected
Expand All @@ -93,6 +97,7 @@ Defines a `PUT` HTTP request.
It should specify at least the following parameters:

- `path`: the route to the resource (example: `/resource/{id}` - where `id` is a path parameter defined below)
- `operationId`: a name unique across the whole document, derived from the handler class name without the `Handler` suffix, with a lowercase first letter (example: `putUserResource`). Clients generated from the specification use it as the method name, so do not rename it once released
- `description`: verbose description of the endpoint's purpose
- `summary`: short description of the endpoint's purpose
- `security`: an array of security scheme(s) to be used—omit if the endpoint is not protected
Expand All @@ -101,20 +106,13 @@ It should specify at least the following parameters:
- `parameters`: an array of `query`/`path` parameters - each parameter is specified as a new `OA\Parameter` object
- `responses`: an array of `OA\Response` objects, each describing a combination of HTTP status codes and their respective response bodies

### Optional parameters

The following parameter is available on every request object but is not required:

- `operationId`: a name for the operation, unique across the whole document (example: `getUserCollection`).
Client generators typically use it as the method name, and `Link` objects use it to refer to an operation.

## Conclusion

To summarize, the typical scenario on working on your own instance of Dotkernel API would follow these steps:

- create new module (example: `Book`)
- add functionality to your new module (routes, entities, repositories, handlers, services, tests etc)
- create file `OpenAPI.php` in the new module and describe each new endpoint
- create file `OpenAPI.php` in the new module and describe each new endpoint, giving each one a unique `operationId`
- declare the tags you used under `tags` in `config/autoload/openapi.global.php`, see [OpenAPI configuration](./configuration.md)
- generate the latest version of a documentation file as described [in this tutorial](./generate-documentation.md)

Expand All @@ -132,16 +130,22 @@ All the endpoints shipped with Dotkernel API are documented there and serve as w

**Q: Which parameters should every request attribute define?**

A: `path`, `description`, `summary`, `tags`, `parameters` and `responses`, plus `requestBody` for the methods that accept a body, and `security` when the endpoint is protected.
A: `path`, `operationId`, `description`, `summary`, `tags`, `parameters` and `responses`, plus `requestBody` for the methods that accept a body, and `security` when the endpoint is protected.

**Q: How do I document an unprotected endpoint?**

A: Omit the `security` parameter.

**Q: Do I need `operationId`?**

A: It is optional in OpenAPI, but recommended, especially if you generate a client from the specification and want stable method names.
It must be unique across the document.
A: Yes.
Dotkernel API sets it on every endpoint, named after the handler without the `Handler` suffix (for example `GetUserCollectionHandler` becomes `getUserCollection`), except the two token endpoints, which share one handler and are named after their routes: `postGenerateToken` and `postRefreshToken`.
A test fails when an endpoint lacks one or when two share one.

**Q: What `operationId` do I use when two routes share one handler?**

A: Name each after its route instead, still starting with the HTTP method, so the IDs stay unique.
Dotkernel API does this for its token endpoints, which share one handler: `postGenerateToken` for `/security/generate-token` and `postRefreshToken` for `/security/refresh-token`.

**Q: What is the difference between `description` and `summary`?**

Expand Down
7 changes: 7 additions & 0 deletions docs/book/v7/tutorials/api-evolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ Vary: Origin

> The `rel` and `type` arguments are optional, they default to `sunset` and `text/html` if no value is provided and are `Link` related parts.

> An operation's `operationId` is part of the contract too: clients generated from the OpenAPI document use it as the method name, so renaming it breaks them even if the route is unchanged.

## FAQ

**Q: What do the `Sunset` and `Link` headers mean?**
Expand Down Expand Up @@ -109,3 +111,8 @@ A: Only handler classes implementing `RequestHandlerInterface`.
**Q: How do I check that the headers are being sent?**

A: Request the endpoint with `curl --head` and inspect the response headers.

**Q: Is renaming an `operationId` a breaking change?**

A: Yes, for clients generated from the OpenAPI document, which use it as the method name.
Treat it like a renamed field: keep the old name until its consumers have moved.
4 changes: 2 additions & 2 deletions docs/book/v7/tutorials/create-book-module-via-dot-maker.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Next you will be prompted to add the relevant components of a module, accepting
* `Allow viewing Books?` (Y): will generate the single resource GET action handler - `GetBookResourceHandler.php`.
* `Allow creating Books?` (Y): will generate the POST action handler for the `Book` entity - `PostBookResourceHandler.php`, as well as the input filter used for validating the data - `CreateBookInputFilter.php`.
* `Allow deleting Books?`, `Allow editing Books?` and `Allow replacing Books?` (N): will generate handlers that reflect the DELETE, PATCH and PUT actions respectively, but are not necessary for this tutorial.
* Following this step, `dot-maker` will automatically generate the `ConfigProvider.php` classes for both the `Api` and `Core` namespaces, as well as the `OpenAPI.php` class which automatically documents the previously generated routes.
* Following this step, `dot-maker` will automatically generate the `ConfigProvider.php` classes for both the `Api` and `Core` namespaces, as well as the `OpenAPI.php` class which automatically documents the previously generated routes, each with its own `operationId`.

You will then be instructed to:

Expand Down Expand Up @@ -468,7 +468,7 @@ curl http://0.0.0.0:8080/book/{id}

**Q: What does `dot-maker` do that I would otherwise do by hand?**

A: It generates the module skeleton — entity, repository, service and interface, handlers, collection, input filter, both `ConfigProvider` classes and the `OpenAPI.php` documentation — and splits the files between the `Api` and `Core` namespaces without being told to.
A: It generates the module skeleton — entity, repository, service and interface, handlers, collection, input filter, both `ConfigProvider` classes and the `OpenAPI.php` documentation, including an `operationId` per endpoint — and splits the files between the `Api` and `Core` namespaces without being told to.

**Q: How do I invoke it?**

Expand Down
Loading