Skip to content

Commit

Permalink
update features
Browse files Browse the repository at this point in the history
Signed-off-by: bidi <[email protected]>
  • Loading branch information
bidi47 committed Nov 18, 2024
1 parent f02c59a commit 95b2fd9
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 78 deletions.
2 changes: 2 additions & 0 deletions docs/book/v5/core-features/content-validation.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
34 changes: 15 additions & 19 deletions docs/book/v5/core-features/dependency-injection.md
Original file line number Diff line number Diff line change
@@ -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`.

Expand All @@ -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
Expand All @@ -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`.
2 changes: 2 additions & 0 deletions docs/book/v5/core-features/error-reporting.md
Original file line number Diff line number Diff line change
@@ -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.

Expand Down
61 changes: 25 additions & 36 deletions docs/book/v5/core-features/exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Check failure on line 25 in docs/book/v5/core-features/exceptions.md

View workflow job for this annotation

GitHub Actions / ci / QA Checks (Documentation Linting [8.1, latest], ubuntu-latest, laminas/laminas-continuous-integra...

Unordered list indentation [Expected: 4; Actual: 2]
* because it has been **consumed** (example: one-time password)

Check failure on line 26 in docs/book/v5/core-features/exceptions.md

View workflow job for this annotation

GitHub Actions / ci / QA Checks (Documentation Linting [8.1, latest], ubuntu-latest, laminas/laminas-continuous-integra...

Unordered list indentation [Expected: 4; Actual: 2]

### `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
Expand All @@ -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`

Check failure on line 62 in docs/book/v5/core-features/exceptions.md

View workflow job for this annotation

GitHub Actions / ci / QA Checks (Documentation Linting [8.1, latest], ubuntu-latest, laminas/laminas-continuous-integra...

Lists should be surrounded by blank lines [Context: "* Create a custom exception ca..."]
* 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

Expand Down Expand Up @@ -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
{
Expand All @@ -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.
24 changes: 11 additions & 13 deletions docs/book/v5/tutorials/api-evolution.md
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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.

Expand All @@ -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.

Expand All @@ -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
...
Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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.
File renamed without changes.
15 changes: 6 additions & 9 deletions docs/book/v5/upgrading.md
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down

0 comments on commit 95b2fd9

Please sign in to comment.