Skip to content

Commit 25b50d5

Browse files
authored
Merge pull request #45 from dotkernel/issue-39
API evolution tutorial
2 parents 5928c6d + 1d540ce commit 25b50d5

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# API Evolution pattern
2+
3+
API evolution: Updating an API while keeping it compatible for existing consumers by adding new features, fixing bugs,
4+
planning and removing outdated features.
5+
6+
## How it works
7+
8+
In DotKernel API we can mark an entire endpoint or a single method as deprecated using attributes on handlers.
9+
We use response headers to inform the consumers about the future changes by using 2 new headers:
10+
11+
1) `Link` - it's a link to the official documentation pointing out the changes that will take place.
12+
2) `Sunset` - this header is a date, indicating when the deprecated resource will potentially become unresponsive.
13+
14+
**Both headers are independent, you can use them separately.**
15+
16+
> Make sure you have the `DeprecationMiddleware:class` piped in your `pipeline` list. In our case it's
17+
> `config/pipeline.php`.
18+
19+
### Marking an entire endpoint as deprecated
20+
21+
When you want to mark an entire resource as deprecated you have to use the `ResourceDeprecation` attribute.
22+
23+
```php
24+
...
25+
#[ResourceDeprecation(
26+
sunset: '2038-01-01',
27+
link: 'https://docs.dotkernel.org/api-documentation/v5/core-features/versioning',
28+
deprecationReason: 'Resource deprecation example.',
29+
rel: 'sunset',
30+
type: 'text/html'
31+
)]
32+
class HomeHandler implements RequestHandlerInterface
33+
{
34+
...
35+
```
36+
37+
In the example above, the ``ResourceDeprecation`` attribute is attached to the class, marking the entire `/` (home)
38+
endpoint as deprecated starting from `2038-01-01`.
39+
40+
Running the following curl will print out the response headers where we can see the **Sunset** and **Link** headers.
41+
42+
```shell
43+
curl --head -X GET http://0.0.0.0:8080 -H "Content-Type: application/json"
44+
```
45+
46+
```shell
47+
HTTP/1.1 200 OK
48+
Host: 0.0.0.0:8080
49+
Date: Mon, 24 Jun 2024 10:23:11 GMT
50+
Connection: close
51+
X-Powered-By: PHP/8.2.20
52+
Content-Type: application/json
53+
Permissions-Policy: interest-cohort=()
54+
Sunset: 2038-01-01
55+
Link: https://docs.dotkernel.org/api-documentation/v5/core-features/versioning;rel="sunset";type="text/html"
56+
Vary: Origin
57+
```
58+
59+
### Marking a method as deprecated
60+
61+
Most of the time you want to deprecate only an endpoint, so you will need to use the `MethodDeprecation` attribute which
62+
has the same parameters, but it attaches to a handler method.
63+
64+
```php
65+
...
66+
class HomeHandler implements RequestHandlerInterface
67+
{
68+
...
69+
use Api\App\Attribute\MethodDeprecation;
70+
71+
#[MethodDeprecation(
72+
sunset: '2038-01-01',
73+
link: 'https://docs.dotkernel.org/api-documentation/v5/core-features/versioning',
74+
deprecationReason: 'Method deprecation example.',
75+
rel: 'sunset',
76+
type: 'text/html'
77+
)]
78+
public function get(): ResponseInterface
79+
{
80+
...
81+
}
82+
}
83+
```
84+
85+
Attaching the `MethodDeprecation` can only be done to HTTP verb methods (`GET`, `POST`, `PUT`, `PATCH` and `DELETE`).
86+
87+
If you followed along you can run the below curl:
88+
89+
```shell
90+
curl --head -X GET http://0.0.0.0:8080 -H "Content-Type: application/json"
91+
```
92+
93+
```shell
94+
HTTP/1.1 200 OK
95+
Host: 0.0.0.0:8080
96+
Date: Mon, 24 Jun 2024 10:54:57 GMT
97+
Connection: close
98+
X-Powered-By: PHP/8.2.20
99+
Content-Type: application/json
100+
Permissions-Policy: interest-cohort=()
101+
Sunset: 2038-01-01
102+
Link: https://docs.dotkernel.org/api-documentation/v5/core-features/versioning;rel="sunset";type="text/html"
103+
Vary: Origin
104+
```
105+
106+
### NOTES
107+
108+
> If `Link` or `Sunset` do not have a value they will not appear in the response headers.
109+
110+
> `Sunset` has to be a **valid** date, otherwise it will throw an error.
111+
112+
> You **cannot** use both `ResourceDeprecation` and `MethodDeprecation` in the same handler.
113+
114+
> Deprecations can only be attached to handler classes that implement `RequestHandlerInterface`.
115+
116+
> The `rel` and `type` arguments are optional, they default to `sunset` and `text/html` if no value was provided and
117+
> are `Link` related parts.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ nav:
4040
- Tutorials:
4141
- "Creating a book module": v5/tutorials/create-book-module.md
4242
- "Token authentication": v5/tutorials/token-authentication.md
43+
- "API Evolution": v5/tutorials/api-evolution.md
4344
- Transition from API Tools:
4445
- "Laminas API Tools vs DotKernel API": v5/transition-from-api-tools/api-tools-vs-dotkernel-api.md
4546
- "Transition Approach": v5/transition-from-api-tools/transition-approach.md

0 commit comments

Comments
 (0)