Skip to content

Commit ec96de4

Browse files
committed
Add first version of new documentation
1 parent e059ec2 commit ec96de4

22 files changed

+1009
-119
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
/vendor
22
.phpunit.result.cache
33
composer.lock
4+
/docs/.nuxt
5+
/docs/dist
6+
/docs/node_modules
7+
/docs/package-lock.json
8+
/docs/static/sw.js

CONTRIBUTIONS.md

+1-43
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,3 @@
11
# Contributions
22

3-
Feel free to contribute. Guide lines contributions:
4-
5-
## Bug fixes
6-
7-
For bug fixes create and issue and pull request if possible.
8-
9-
## Ideas
10-
11-
Use the discussion functionality and propose your idea:
12-
13-
- What you want to solve?
14-
- Sample proof of concept code? (just how it could look)
15-
16-
## Wait to take in account
17-
18-
- Always design your classes with dependency injection in mind (possibly constructor).
19-
- Always think about tests -> how they should be written and if it is easy.
20-
21-
## Lint and tests
22-
23-
```bash
24-
composer run check
25-
```
26-
27-
We are using set of tools to ensure that the code is consistent. Run this before pushing your code changes.
28-
29-
### [PHPStan](https://phpstan.org)
30-
31-
```bash
32-
composer run check
33-
```
34-
35-
### [Rector](https://github.com/rectorphp/rector)
36-
37-
```bash
38-
composer run check
39-
```
40-
41-
### [Easy coding standard](https://github.com/symplify/easy-coding-standard)
42-
43-
```bash
44-
composer run check
45-
```
3+
See our official documentation at [php-sdk-builder.wrk-flow.com/contributions](https://php-sdk-builder.wrk-flow.com/contributions)

README.md

+16-72
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,30 @@
1-
### A base package for building unified API SDKs with type strict and dependency in mind
2-
3-
> Work in progress
1+
### Build unified APIs with dependency injection and strict code in mind.
42

53
```bash
64
composer require wrkflow/php-api-sdk-builder
75
```
86

9-
## How to use API SDK
10-
11-
Every API should have only 2 parameters: `environment` and `ApiFactory`.
12-
13-
- Environment defines base url, headers. Environment should accept credentials.
14-
- ApiFactory provides request factory, stream factory, client factory and container to allow dependency injection.
15-
- You can use already used PSR-7 HTTP library in your code (or use [Nyholm/psr7](https://github.com/Nyholm/psr7))
16-
- You can use already pre-pared container wrappers
17-
- Laravel: `new \WrkFlow\ApiSdkBuilder\Containers\LaravelContainerFactory()`
18-
- Or provide your own container by implementing SDKContainerFactoryContract
19-
20-
You can use prepared
21-
22-
```php
23-
// Better - use dependency injections in your methods
24-
$container = app(LaravelContainerFactory::class);
25-
$api = new MyApi(
26-
new LiveEnvironment($apiKey),
27-
new ApiFactory(
28-
new RequestFactory(),
29-
new Client(),
30-
new StreamFactory(),
31-
$container
32-
)
33-
);
34-
35-
// Your own response object
36-
$response = $api->namespaces()->paginate();
37-
```
38-
39-
## How to build API SDK
40-
41-
### Architecture
42-
43-
Each API consists:
44-
45-
- environments
46-
- endpoints (and input options)
47-
- headers
48-
- responses (you are advised to use them, but this library does not force them).
49-
50-
All endpoints and responses allows dependency injection. **Ensure that parent __construct arguments are not renamed**.
51-
52-
#### Environments
53-
54-
> Use `YourApi\Environments` namespace
55-
56-
If you are planning to have multiple environments I would recommend creating `AbstractYourApiEnvironment` and then
57-
creating something like `LiveEnvironment`.
58-
59-
Environment are a good place to get "consumer" data to setup the API (credentials, headers, etc).
60-
61-
#### Headers
62-
63-
> Use `YourApi\Headers` namespace
64-
65-
For building passing / using headers you can use pre-build (or create your own) classes that will allow stacking
66-
headers into reusable classes.
7+
> This library is still in its early stages. But the main concepts will probably remain same.
678
68-
When ever you want to pass headers in environment or return it in endpoint you are advised to use header classes but you
69-
can return a map of headers 'key' => 'header' or 'key' => 'headers'.
9+
## Features
7010

71-
**Available classes (fell free to PR more):**
11+
![img](https://img.shields.io/badge/PHPStan-8-blue)
12+
![php](https://img.shields.io/badge/PHP-8.1-B0B3D6)
7213

73-
- JsonContentTypeHeaders
74-
- AcceptsJsonHeaders
75-
- JsonHeaders (sets the content type and accepts json headers)
14+
- 🛠 Dependency injection using your favorite framework (Laravel, _PR for more_)
15+
- ✅ Uses PSR packages you already use for HTTP/S communication
16+
- 🏆 Forcing type strict implementation for input (request options) and output (`Response`)
17+
- 🎗 Encouraging `Data transfer objects`
18+
- 🎭 Re-usable headers using objects
7619

77-
Each header class can chain other headers (check JsonHeaders file).
20+
[📖 Read the documentation](https://php-sdk-builder.wrk-flow.com)
7821

79-
#### Endpoints
22+
## APIs packages
8023

81-
TODO
24+
> List of APIs made with this package
8225
83-
#### Naming conventions
26+
- Maggelano Channel manager - _TODO_
8427

85-
TODO
28+
## Development
8629

30+
For development read [CONTRIBUTIONS](https://php-sdk-builder.wrk-flow.com/contributions)

composer.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,14 @@
5656
"allow-plugins": {
5757
"symfony/thanks": false
5858
}
59-
}
59+
},
60+
"archive": {
61+
"exclude": ["/docs"]
62+
},
63+
"funding": [
64+
{
65+
"type": "github",
66+
"url": "https://github.com/sponsors/pionl"
67+
}
68+
]
6069
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
---
2+
title: Architecture and conventions
3+
menuTitle: Architecture
4+
subtitle: 'To properly create your API it is important to understand the conventions and the architecture 🚀'
5+
category: Architecture
6+
position: 11
7+
---
8+
9+
API is built using these conventions:
10+
11+
- **API object:** provides the API interface
12+
- **Environments:** provides user customization of the API
13+
- **Endpoints:** provides a way to call API endpoint and return response
14+
- **Options:** provides ability to send data to the API endpoint
15+
- **Response:** Holds the response data with defined "options".
16+
- **Entities:** Data transfer objects for responses.
17+
- **Transformers:** Transform classes that will transform any data (response array) to entity.
18+
19+
## API
20+
21+
> See [Start building / Usage](/start-building/create-api)
22+
23+
API is the main class that holds:
24+
25+
- which environment we should use,
26+
- which endpoints are available
27+
- defines base headers for the environment
28+
29+
### Conventions
30+
31+
- Always return the type of the endpoint.
32+
- Use `MyEndpoint::class` syntax instead of strings.
33+
- Do not alter `__construct`, use Environments for custom data.
34+
35+
#### Name
36+
37+
- If you are using DDD use `Api` namespace in your domain. Like `Github\Api` (for private usage)
38+
- Name your class `GithubApi` (use Api suffix)
39+
- For endpoints use `camelCase` naming.
40+
41+
### Example
42+
43+
```php
44+
namespace MagellanoApi;
45+
46+
use MagellanoApi\Endpoints\Units\UnitsEndpoint;
47+
use MagellanoApi\Endpoints\UnitsAvailabilities\UnitsAvailabilitiesEndpoint;
48+
use WrkFlow\ApiSdkBuilder\AbstractApi;
49+
use WrkFlow\ApiSdkBuilder\Headers\JsonHeaders;
50+
51+
class MagellanoApi extends AbstractApi
52+
{
53+
public function headers(): array
54+
{
55+
return [new JsonHeaders()];
56+
}
57+
58+
public function units(): UnitsEndpoint
59+
{
60+
return $this->makeEndpoint(UnitsEndpoint::class);
61+
}
62+
63+
public function unitsAvailabilities(): UnitsAvailabilitiesEndpoint
64+
{
65+
return $this->makeEndpoint(UnitsAvailabilitiesEndpoint::class);
66+
}
67+
}
68+
```
69+
70+
## ApiFactory
71+
72+
> See [Start building / Usage](/start-building/use-it)
73+
74+
Used for passing PSR implementations for HTTP/s communication and container factory (for dependency injection).
75+
76+
Factory is later used in your API to build endpoints, responses.
77+
78+
## Transformers
79+
80+
- Try to indicate within the name of class what is the input / output.
81+
- Always add `transform(IntType $object): OutType` function that will make the transformation.
82+
- Extend `AbstractJsonTransformer` if you are converting array to entity object. Contains helper method from `WorksWithJson`
83+
84+
```php
85+
use WrkFlow\ApiSdkBuilder\Transformers\AbstractJsonTransformer;
86+
87+
class JsonToUnitAvailabilityEntity extends AbstractJsonTransformer
88+
{
89+
private const KEY_AVAILABILITY_STATUS = 'availabilityStatus';
90+
91+
public function transform(array $item): UnitAvailabilityEntity
92+
{
93+
$id = $this->getInt($item, 'ID');
94+
$isAvailable = $this->getBool($item, 'isAvailable');
95+
96+
$availabilityStates = [];
97+
if (array_key_exists(self::KEY_AVAILABILITY_STATUS, $item) === true
98+
&& is_array($item[self::KEY_AVAILABILITY_STATUS]) === true) {
99+
foreach ($item[self::KEY_AVAILABILITY_STATUS] as $item) {
100+
$availabilityStates[] = new UnitAvailabilityStateEntity(
101+
day: $item['day'],
102+
state: AvailabilityState::from($item['status']),
103+
);
104+
}
105+
}
106+
107+
return new UnitAvailabilityEntity(
108+
id: $id,
109+
isAvailable: $isAvailable,
110+
availabilityStates: $availabilityStates
111+
);
112+
}
113+
}
114+
```
115+
116+
## Entities
117+
118+
Entities are Data transfer objects. We do place them in `Entities` namespace when it is used by more responses. Otherwise, it is located in same folder as the endpoint.
119+
120+
The entity should be immutable.
121+
122+
```php
123+
class UnitAvailabilityEntity
124+
{
125+
/**
126+
* @param array<UnitAvailabilityStateEntity> $availabilityStates can be empty if hideDetails is true
127+
*/
128+
public function __construct(
129+
public readonly int $id,
130+
public readonly bool $isAvailable,
131+
public readonly array $availabilityStates
132+
) {
133+
}
134+
}
135+
```
136+
137+
## Concerns (utils)
138+
139+
### WorksWithJson
140+
141+
Trait that allows you to access values from an array with type safe manner.
142+
143+
```php
144+
/**
145+
* @param array<string, mixed> $data
146+
*/
147+
public function getInt(array $data, string $key): ?int;
148+
149+
/**
150+
* @param array<string, mixed> $data
151+
*/
152+
public function getFloat(array $data, string $key): ?float;
153+
154+
/**
155+
* @param array<string, mixed> $data
156+
*/
157+
public function getBool(array $data, string $key): ?bool;
158+
159+
public function floatVal(mixed $value): ?float;
160+
161+
public function intVal(mixed $value): ?int;
162+
163+
public function boolVal(mixed $value): ?bool;
164+
```

0 commit comments

Comments
 (0)