From 95b2fd9242242691eb0dc740d0d6bbe23d8385cb Mon Sep 17 00:00:00 2001 From: bidi Date: Mon, 18 Nov 2024 18:13:56 +0200 Subject: [PATCH] update features Signed-off-by: bidi --- .../v5/core-features/content-validation.md | 2 + .../v5/core-features/dependency-injection.md | 34 +++++------ docs/book/v5/core-features/error-reporting.md | 2 + docs/book/v5/core-features/exceptions.md | 61 ++++++++----------- docs/book/v5/tutorials/api-evolution.md | 24 ++++---- .../v5/{core-features => tutorials}/cors.md | 0 docs/book/v5/upgrading.md | 15 ++--- mkdocs.yml | 2 +- 8 files changed, 62 insertions(+), 78 deletions(-) rename docs/book/v5/{core-features => tutorials}/cors.md (100%) diff --git a/docs/book/v5/core-features/content-validation.md b/docs/book/v5/core-features/content-validation.md index ec01f34..2b1f548 100644 --- a/docs/book/v5/core-features/content-validation.md +++ b/docs/book/v5/core-features/content-validation.md @@ -1,5 +1,7 @@ # Content Negotiation +> Introduced in Dotkernel API 4.5.0 + **Content Negotiation** is performed by an application in order : - To match the requested representation as specified by the client via the Accept header with a representation the diff --git a/docs/book/v5/core-features/dependency-injection.md b/docs/book/v5/core-features/dependency-injection.md index 0ef7a19..967d280 100644 --- a/docs/book/v5/core-features/dependency-injection.md +++ b/docs/book/v5/core-features/dependency-injection.md @@ -1,22 +1,20 @@ # Dependency Injection -Dependency injection is a design pattern used in software development to implement inversion of control. In simpler -terms, it's the act of providing dependencies for an object during instantiation. +> Introduced in Dotkernel API 5.0.0 -In PHP, dependency injection can be implemented in various ways, including through constructor injection, setter -injection and property injection. +Dependency injection is a design pattern used in software development to implement inversion of control. +In simpler terms, it's the act of providing dependencies for an object during instantiation. -Dotkernel API, through its [dot-dependency-injection](https://github.com/dotkernel/dot-dependency-injection) package -focuses only on constructor injection. +In PHP, dependency injection can be implemented in various ways, including through constructor injection, setter injection and property injection. + +Dotkernel API, through its [dot-dependency-injection](https://github.com/dotkernel/dot-dependency-injection) package focuses only on constructor injection. ## Usage -**Dotkernel API** comes out of the box with the -[dot-dependency-injection](https://github.com/dotkernel/dot-dependency-injection) package, which provides all we need for -injecting dependencies into any object you want. +**Dotkernel API** comes out of the box with the [dot-dependency-injection](https://github.com/dotkernel/dot-dependency-injection) package, which provides all we need for injecting dependencies into any object you want. -`dot-dependency-injection` determines the dependencies by looking at the `#[Inject]` attribute, added to the constructor -of a class. Dependencies are specified as separate parameters of the `#[Inject]` attribute. +`dot-dependency-injection` determines the dependencies by looking at the `#[Inject]` attribute, added to the constructor of a class. +Dependencies are specified as separate parameters of the `#[Inject]` attribute. For our example we will inject `UserService` and `config` dependencies into a `UseHandler`. @@ -37,11 +35,9 @@ class UserHandler implements RequestHandlerInterface } ``` -> If your class needs the value of a specific configuration key, you can specify the path using dot notation: -> `config.example` +> If your class needs the value of a specific configuration key, you can specify the path using dot notation `config.example`. -The next step is to register the class in the `ConfigProvider` under `factories` using -`Dot\DependencyInjection\Factory\AttributedServiceFactory::class` +The next step is to register the class in the `ConfigProvider` under `factories` using `Dot\DependencyInjection\Factory\AttributedServiceFactory::class` ```php public function getDependencies(): array @@ -54,8 +50,8 @@ public function getDependencies(): array } ``` -That's it. When your object is instantiated from the container, it will automatically have its -dependencies resolved. +That's it. +When your object is instantiated from the container, it will automatically have its dependencies resolved. -> Dependencies injection is available to any object within Dotkernel API. For example, you can inject dependencies in a -> service, a handler and so on, simply by registering it in the `ConfigProvider`. +> Dependencies injection is available to any object within Dotkernel API. +> For example, you can inject dependencies in a service, a handler and so on, simply by registering it in the `ConfigProvider`. diff --git a/docs/book/v5/core-features/error-reporting.md b/docs/book/v5/core-features/error-reporting.md index a429a08..00c05ea 100644 --- a/docs/book/v5/core-features/error-reporting.md +++ b/docs/book/v5/core-features/error-reporting.md @@ -1,5 +1,7 @@ # Error reporting endpoint +> Backward incompatibility introduced in Dotkernel API 4.1.0 + The error reporting endpoint was designed to allow the **frontend developers** of your API to report any bugs they encounter in a secure way that is fully under your control. To prevent unauthorized usage, the endpoint is protected by a token in the request's header. diff --git a/docs/book/v5/core-features/exceptions.md b/docs/book/v5/core-features/exceptions.md index 764287f..dab634c 100644 --- a/docs/book/v5/core-features/exceptions.md +++ b/docs/book/v5/core-features/exceptions.md @@ -2,61 +2,50 @@ ## What are exceptions? -Exceptions are a powerful mechanism for handling errors and other exceptional conditions that may occur during the -execution of a script. -They provide a way to manage errors in a structured and controlled manner, separating error-handling code from regular -code. +Exceptions are a powerful mechanism for handling errors and other exceptional conditions that may occur during the execution of a script. +They provide a way to manage errors in a structured and controlled manner, separating error-handling code from regular code. -## How we use exceptions? +## How we use exceptions -When it comes to handling exceptions, **Dotkernel API** relies on the usage of easy-to-understand, problem-specific -exceptions. - -Out-of-the-box we provide the following custom exceptions: +When it comes to handling exceptions, **Dotkernel API** relies on the usage of easy-to-understand, problem-specific exceptions. +Below we will list the available custom exceptions. ### `BadRequestException` thrown when -* client tries to create/update resource, but the data from the request is invalid/incomplete (example: client tries to - create an account, but does not send the required `identity` field) +* The Client tries to **create/update resource**, but the **request data is invalid/incomplete** (example: client tries to create an account, but does not send the required `identity` field) ### `ConflictException` thrown when -* resource cannot be created because a different resource with the same identifier already exists (example: cannot - change existing user's identity because another user with the same identity already exists) -* resource cannot change its state because it is already in the specified state (example: user cannot be activated - because it is already active) +* The **resource cannot be created** because a different resource with the same identifier **already exists** (example: cannot change existing user's identity because another user with the same identity already exists) +* The **resource cannot change its state** because it is **already in the specified state** (example: user cannot be activated because it is already active) ### `ExpiredException` thrown when -* resource cannot be accessed because it expired (example: account activation link) -* resource cannot be accessed because it has been consumed (example: one-time password) +* The **resource cannot be accessed** + * because it has **expired** (example: account activation link) + * because it has been **consumed** (example: one-time password) ### `ForbiddenException` thrown when -* resource cannot be accessed by the authenticated client (example: client authenticated as regular user sends - a `GET /admin` request) +* The **resource cannot be accessed** by the authenticated client's **role** (example: client authenticated as regular user sends a `GET /admin` request) ### `MethodNotAllowedException` thrown when -* client tries to interact with a resource via an invalid HTTP request method (example: client sends a `PATCH /avatar` - request) +* The client tries to interact with a resource via an **invalid HTTP request method** (example: client sends a `PATCH /avatar` request) ### `NotFoundException` thrown when -* client tries to interact with a resource that does not exist on the server (example: client sends - a `GET /resource-does-not-exist` request) +* The client tries to interact with a **resource that does not exist** on the server (example: client sends a `GET /resource-does-not-exist` request) ### `UnauthorizedException` thrown when -* resource cannot be accessed because the client is not authenticated (example: unauthenticated client sends - a `GET /admin` request) +* The **resource cannot be accessed** because the **client is not authenticated** (example: unauthenticated client sends a `GET /admin` request) -## How it works? +## How it works -During a request, if there is no uncaught exception **Dotkernel API** will return a JSON response with the data provided -by the handler that handled the request. +During a request, if there is no uncaught exception, **Dotkernel API** will return a JSON response with the data provided by the handler that processed the request. -Else, it will build and send a response based on the exception thrown: +Otherwise, it will build and send a response based on the exception thrown: * `BadRequestException` will return a `400 Bad Request` response * `UnauthorizedException` will return a `401 Unauthorized` response @@ -67,11 +56,12 @@ Else, it will build and send a response based on the exception thrown: * `ExpiredException` will return a `410 Gone` response * `MailException`, `RuntimeException` and the generic `Exception` will return a `500 Internal Server Error` response -## How to extend? +## How to extend -In this example we will create a custom exception called `CustomException`, place it next to the already existing custom -exceptions (you can use your preferred location) and finally return a custom HTTP status code when `CustomException` is -encountered. +In this example we will +* Create a custom exception called `CustomException` +* Place it next to the already existing custom exceptions (you can use your preferred location) +* Return a custom HTTP status code when `CustomException` is encountered. ### Step 1: Create exception file @@ -106,8 +96,7 @@ Save and close the file. ### Step 3: Test for failure -Access your API's home page URL and make sure it returns `500 Internal Server Error` HTTP status code and the following -content: +Access your API's home page URL and make sure it returns `500 Internal Server Error` HTTP status code and the following content: ```json { @@ -133,5 +122,5 @@ Save and close the file. ### Step 5: Test for success -Again, access your API's home page URL, which should return the same content. +Access your API's home page URL, which should return the same content. Notice that this time it returns `418 I'm a teapot` HTTP status code. diff --git a/docs/book/v5/tutorials/api-evolution.md b/docs/book/v5/tutorials/api-evolution.md index 02b425b..2fd0c00 100644 --- a/docs/book/v5/tutorials/api-evolution.md +++ b/docs/book/v5/tutorials/api-evolution.md @@ -1,7 +1,6 @@ # API Evolution pattern -API evolution: Updating an API while keeping it compatible for existing consumers by adding new features, fixing bugs, -planning and removing outdated features. +API evolution: Updating an API while keeping it compatible for existing consumers by adding new features, fixing bugs, planning and removing outdated features. ## How it works @@ -13,10 +12,10 @@ We use response headers to inform the consumers about the future changes by usin **Both headers are independent, you can use them separately.** -> Make sure you have the `DeprecationMiddleware:class` piped in your `pipeline` list. In our case it's -> `config/pipeline.php`. +> Make sure you have the `DeprecationMiddleware:class` piped in your `pipeline` list. +> In our case it's `config/pipeline.php`. -### Marking an entire endpoint as deprecated +## Marking an entire endpoint as deprecated When you want to mark an entire resource as deprecated you have to use the `ResourceDeprecation` attribute. @@ -34,8 +33,7 @@ class HomeHandler implements RequestHandlerInterface ... ``` -In the example above, the ``ResourceDeprecation`` attribute is attached to the class, marking the entire `/` (home) -endpoint as deprecated starting from `2038-01-01`. +In the example above, the `ResourceDeprecation` attribute is attached to the class, marking the entire `/` (home) endpoint as deprecated starting from `2038-01-01`. Running the following curl will print out the response headers where we can see the **Sunset** and **Link** headers. @@ -56,10 +54,9 @@ Link: https://docs.dotkernel.org/api-documentation/v5/core-features/versioning;r Vary: Origin ``` -### Marking a method as deprecated +## Marking a method as deprecated -Most of the time you want to deprecate only an endpoint, so you will need to use the `MethodDeprecation` attribute which -has the same parameters, but it attaches to a handler method. +Most of the time you want to deprecate only an endpoint, so you will need to use the `MethodDeprecation` attribute which has the same parameters, but it attaches to a handler method. ```php ... @@ -90,6 +87,8 @@ If you followed along you can run the below curl: curl --head -X GET http://0.0.0.0:8080 -H "Content-Type: application/json" ``` +The response lists the **Sunset** and **Link** headers. + ```shell HTTP/1.1 200 OK Host: 0.0.0.0:8080 @@ -103,7 +102,7 @@ Link: https://docs.dotkernel.org/api-documentation/v5/core-features/versioning;r Vary: Origin ``` -### NOTES +## NOTES > If `Link` or `Sunset` do not have a value they will not appear in the response headers. @@ -113,5 +112,4 @@ Vary: Origin > Deprecations can only be attached to handler classes that implement `RequestHandlerInterface`. -> The `rel` and `type` arguments are optional, they default to `sunset` and `text/html` if no value was provided and -> are `Link` related parts. +> The `rel` and `type` arguments are optional, they default to `sunset` and `text/html` if no value was provided and are `Link` related parts. diff --git a/docs/book/v5/core-features/cors.md b/docs/book/v5/tutorials/cors.md similarity index 100% rename from docs/book/v5/core-features/cors.md rename to docs/book/v5/tutorials/cors.md diff --git a/docs/book/v5/upgrading.md b/docs/book/v5/upgrading.md index ffc6ddd..c22d29b 100644 --- a/docs/book/v5/upgrading.md +++ b/docs/book/v5/upgrading.md @@ -1,18 +1,15 @@ # Upgrades Dotkernel API does not provide an automatic upgrade path. - Instead, the recommended procedure is to manually implement each modification listed in [releases](https://github.com/dotkernel/api/releases). -Additionally, releases info can also be accessed as an [RSS](https://github.com/dotkernel/api/releases.atom) feed. +Additionally, release info can also be accessed as an [RSS](https://github.com/dotkernel/api/releases.atom) feed. ## Upgrade procedure Once you clone Dotkernel API, you will find a [CHANGELOG.md](https://github.com/dotkernel/api/blob/5.0/CHANGELOG.md) file in the root of the project. +This file contains a list of already implemented features in reverse chronological order. +You can use this file to track the version of your copy of Dotkernel API. -This contains a list of already implemented features in reversed chronological order. -You can use this file to track the version your copy of Dotkernel API is at. - -When there is a new release, you need to run through it and implement in your project the modifications from each pull request. - -Finally, copy the release info and paste it at the beginning of your project's CHANGELOG.md file. -This way you will be able to track your API's version info and keep your project up-to-date. +For each new release you need implement the modifications from its pull requests in your project. +It is recommended to copy the release info into your project's CHANGELOG.md file. +This allows you to track your API's version and keep your project up-to-date with future releases. diff --git a/mkdocs.yml b/mkdocs.yml index d952ee8..e3f4c5b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -31,7 +31,6 @@ nav: - "Authorization": v5/core-features/authorization.md - "Content Validation": v5/core-features/content-validation.md - "Exceptions": v5/core-features/exceptions.md - - "CORS": v5/core-features/cors.md - "Dependency Injection": v5/core-features/dependency-injection.md - "Error reporting": v5/core-features/error-reporting.md - Commands: @@ -40,6 +39,7 @@ nav: - "Display available endpoints": v5/commands/display-available-endpoints.md - "Generate tokens": v5/commands/generate-tokens.md - Tutorials: + - "Setting up CORS": v5/tutorials/cors.md - "Creating a book module": v5/tutorials/create-book-module.md - "Token authentication": v5/tutorials/token-authentication.md - "API Evolution": v5/tutorials/api-evolution.md