Skip to content

Commit e0cdfaf

Browse files
committed
docs(readme): change all documentation in readme, and add contributing documentation
1 parent d4395eb commit e0cdfaf

File tree

2 files changed

+226
-46
lines changed

2 files changed

+226
-46
lines changed

CONTRIBUTING.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Contribution/Development
2+
3+
This section talks about how to contribute and develop in the package.
4+
5+
## Index
6+
7+
- [Contribution](#contribution)
8+
- [Development](#development)
9+
- [Code Analysis](#code-analysis)
10+
- [Hooks](#hooks)
11+
12+
## Contribution
13+
14+
To contribute to the evolution of the project it is necessary to follow some steps:
15+
16+
- To create a branch, follow the `[PREFIX]` pattern. The accepted prefixes are those listed below:
17+
- `hotfix`: To fix a production bug in the application;
18+
- `fix`: To fix a bug in the application;
19+
- `feature`: To insert a new feature into the application;
20+
- `build`: Changes that affect the build system or external dependencies (examples: composer, dockerfile, dockercompose);
21+
- `ci`: Changes to CI configuration files and scripts (examples: gitlab-ci, sonarqube, lints, security);
22+
- `docs`: Only modification of documentation (examples: Readme, Changelog);
23+
- `performance`: A code change that improves performance (examples: response time, memory consumption);
24+
- `refactor`: A code change that does not fix a bug or add a feature;
25+
- `style`: Changes that do not affect the meaning of the code (examples: white space, formatting, lint, missing semicolon, etc.);
26+
- `test`: Adding missing tests or correcting existing tests;
27+
- `chore`: When you do everything and a little in the branch (write documentation, format, add tests, clean up useless code, etc.)
28+
29+
## Development
30+
31+
### Code Analysis
32+
33+
A code analyzer is very useful so that we can program in a certain way following the recommendations of each analyzer.
34+
35+
Currently in the project there is 1 analyzer:
36+
37+
- PHP Code Sniffer
38+
39+
#### Linter
40+
41+
This project uses the `PhpCsFixer` linter.
42+
43+
There are several scripts in `composer.json` for Code Sniffer:
44+
45+
- `lint-diff`: Runs the linter only for files that have been modified
46+
- `lint-diff-staged`: Runs the linter for files that have been modified and are in the `staged` section of git
47+
- `lint-fix`: Runs the linter and fixes only the files that have been modified
48+
- `lint-fix-staged`: Runs the linter and fixes the files that have been modified and are in the `staged` section of git
49+
50+
> The configuration file is in the root of the project called `.php-cs-fixer.php`
51+
52+
#### Php Stan
53+
54+
This project makes use of the [*phpstan*](https://phpstan.org/) package, which performs static analysis on the code, validating quality rules. It is possible to find errors in the code without executing it.
55+
56+
There is the script in `composer.json` to perform analysis:
57+
58+
- `analyse`: Analyzes according to `phpstan` rules.
59+
60+
> To look at other available options, see the [*PHPStan*](https://phpstan.org/config-reference) documentation
61+
62+
### Hooks
63+
64+
There are three git hooks:
65+
66+
To activate them, just type the following command:
67+
68+
```
69+
npm run prepare
70+
```
71+
72+
- **commit-msg**: It is checked when you finish committing to check if the message complies with the rules.
73+
- **pre-commit**: Before each commit, it is checked whether the files that are staged in git comply with the rules
74+
- **prepare-commit-msg**: Prepares the commit to comply with the recommendations

README.md

Lines changed: 152 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,181 @@
1-
# :package_description
2-
3-
[![Latest Version on Packagist](https://img.shields.io/packagist/v/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug)
4-
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/:vendor_slug/:package_slug/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3Arun-tests+branch%3Amain)
5-
[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/:vendor_slug/:package_slug/fix-php-code-style-issues.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
6-
[![Total Downloads](https://img.shields.io/packagist/dt/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug)
7-
<!--delete-->
8-
---
9-
This repo can be used to scaffold a Laravel package. Follow these steps to get started:
1+
# Laravel Api Problem
2+
3+
[![Latest Version on Packagist](https://img.shields.io/packagist/v/pedrosalpr/laravel-api-problem.svg?style=flat-square)](https://packagist.org/packages/pedrosalpr/laravel-api-problem)
4+
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/pedrosalpr/laravel-api-problem/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/pedrosalpr/laravel-api-problem/actions?query=workflow%3Arun-tests+branch%3Amain)
5+
[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/pedrosalpr/laravel-api-problem/fix-php-code-style-issues.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/pedrosalpr/laravel-api-problem/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
6+
[![Total Downloads](https://img.shields.io/packagist/dt/pedrosalpr/laravel-api-problem.svg?style=flat-square)](https://packagist.org/packages/pedrosalpr/laravel-api-problem)
7+
8+
The objective of this package is to facilitate error outputs from API requests in accordance with the [RFC 9457](https://datatracker.ietf.org/doc/rfc9457/) standard.
9+
10+
It transforms error outputs into json format with the following characteristics:
11+
- header:
12+
- `Content-Type: application/problem+json`
13+
- response:
14+
- `type`: URI that identifies the type of error that occured, for example `https://example.com/validation-error`.
15+
- `title`: Human-readable identifier, usually the same type field should have the same title field alongside. An example would be something like Form validation failed.
16+
- `status`: A copy of the HTTP status code.
17+
- `detail`: More information about the specific problem, and if it's appropriate also steps to correct it. For example information about a form validation problem Username is already taken, please choose a different username.
18+
- `instance`: An identifier for this specific occurence, which may not be useful to the client but may be included in a bug report for example.
19+
- **Additional fields**: Any fields may be added to give additional information, and consuming clients are expected to ignore any that they don't have specific support for.
20+
- `timestamp`: (RFC 9457 enhancement): A timestamp indicating when the problem was generated. This helps in logging and tracing the error, especially in systems where timing is critical.
21+
22+
Example:
23+
24+
Server Response:
25+
```bash
26+
HTTP/1.1 422 Unprocessable Entity
27+
Content-Type: application/problem+json
28+
Content-Language: en
29+
{
30+
"status": 422,
31+
"type": "https://example.test/validation-error",
32+
"title": "Form validation failed",
33+
"detail": "One or more fields have validation errors. Please check and try again.",
34+
"instance": "http://example.test/api/test/1",
35+
"timestamp": "2024-02-09T11:55:51.252968Z",
36+
"errors": [
37+
{
38+
"name": "username",
39+
"reason": "Username is already taken."
40+
},
41+
{
42+
"name": "email",
43+
"reason": "Email format is invalid."
44+
}
45+
]
46+
}
47+
```
1048

11-
1. Press the "Use this template" button at the top of this repo to create a new repo with the contents of this skeleton.
12-
2. Run "php ./configure.php" to run a script that will replace all placeholders throughout all the files.
13-
3. Have fun creating your package.
14-
4. If you need help creating a package, consider picking up our <a href="https://laravelpackage.training">Laravel Package Training</a> video course.
15-
---
16-
<!--/delete-->
17-
This is where your description should go. Limit it to a paragraph or two. Consider adding a small example.
49+
## Installation
1850

19-
## Support us
51+
You can install the package via composer:
2052

21-
[<img src="https://github-ads.s3.eu-central-1.amazonaws.com/:package_name.jpg?t=1" width="419px" />](https://spatie.be/github-ad-click/:package_name)
53+
```bash
54+
composer require pedrosalpr/laravel-api-problem
55+
```
2256

23-
We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
57+
> Only works in Laravel 9 and 10.
2458
25-
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).
59+
## Usage
2660

27-
## Installation
61+
### Default Mode
2862

29-
You can install the package via composer:
63+
To use it, just go to the `register` method within `Exceptions\Handler.php` and add the following code:
3064

31-
```bash
32-
composer require :vendor_slug/:package_slug
65+
```php
66+
use Pedrosalpr\LaravelApiProblem\LaravelApiProblem;
67+
68+
public function register(): void
69+
{
70+
...
71+
72+
$this->renderable(function (\Throwable $e, Request $request) {
73+
if ($request->is('api/*') || $this->shouldReturnJson($request, $e)) {
74+
$apiProblem = new LaravelApiProblem($e, $request);
75+
return $apiProblem->render();
76+
}
77+
});
78+
}
3379
```
3480

35-
You can publish and run the migrations with:
81+
If you want to debug, just add the following line before the return:
3682

37-
```bash
38-
php artisan vendor:publish --tag=":package_slug-migrations"
39-
php artisan migrate
40-
```
83+
`dd($apiProblem->toDebuggableArray());`
4184

42-
You can publish the config file with:
85+
#### Creating Exceptions in the Api Problem pattern
4386

44-
```bash
45-
php artisan vendor:publish --tag=":package_slug-config"
46-
```
87+
There is the possibility of creating exceptions that extend `LaravelApiProblemException`.
88+
89+
This already makes it easier to transform the exception into the Api Problem pattern.
90+
91+
To do this, simply run the following command:
4792

48-
This is the contents of the published config file:
93+
`php artisan laravel-api-problem:exception {name}`
94+
95+
For example:
96+
97+
`php artisan laravel-api-problem:exception DummyException`
98+
99+
This creates a class exception inside `Exceptions\ApiProblem`;
49100

50101
```php
51-
return [
52-
];
102+
<?php
103+
104+
namespace App\Exceptions\ApiProblem;
105+
106+
use Pedrosalpr\LaravelApiProblem\Exceptions\LaravelApiProblemException;
107+
108+
class DummyException extends LaravelApiProblemException
109+
{
110+
111+
}
53112
```
54113

55-
Optionally, you can publish the views using
114+
### Custom Mode
56115

57-
```bash
58-
php artisan vendor:publish --tag=":package_slug-views"
116+
If you want to customize an `Api Problem` class to add your guidelines for which error responses should be returned, simply extend the class with the following command:
117+
118+
`php artisan laravel-api-problem:extend`
119+
120+
For example:
121+
122+
`php artisan laravel-api-problem:extend DummyApiProblem`
123+
124+
This creates a class Api Problem inside `ApiProblem`;
125+
126+
```php
127+
<?php
128+
129+
namespace App\ApiProblem;
130+
131+
use Illuminate\Http\Request;
132+
use Illuminate\Http\Response;
133+
use Pedrosalpr\LaravelApiProblem\Http\LaravelHttpApiProblem;
134+
use Pedrosalpr\LaravelApiProblem\LaravelApiProblem;
135+
136+
class DummyApiProblem extends LaravelApiProblem
137+
{
138+
public function __construct(
139+
protected \Throwable $exception,
140+
protected Request $request
141+
) {
142+
match (get_class($exception)) {
143+
\Exception::class => $this->dummy(),
144+
default => parent::__construct($exception, $request)
145+
};
146+
}
147+
148+
protected function dummy()
149+
{
150+
$extensions = [
151+
'errors' => "Dummy",
152+
];
153+
$this->apiProblem = new LaravelHttpApiProblem(
154+
Response::HTTP_I_AM_A_TEAPOT,
155+
$this->exception->getMessage(),
156+
$this->getUriInstance(),
157+
$extensions
158+
);
159+
}
160+
}
59161
```
60162

61-
## Usage
163+
And within the match, add the names of the exceptions classes with their respective methods, such as `dummy()`.
164+
165+
And in the `Handler.php` file replace the `LaravelApiProblem` object instance to `DummyApiProblem`.
62166

63167
```php
64-
$variable = new VendorName\Skeleton();
65-
echo $variable->echoPhrase('Hello, VendorName!');
168+
$this->renderable(function (\Throwable $e, Request $request) {
169+
if ($request->is('api/*') || $this->shouldReturnJson($request, $e)) {
170+
$apiProblem = new DummyApiProblem($e, $request);
171+
return $apiProblem->render();
172+
}
173+
});
66174
```
67175

68176
## Testing
69177

70-
```bash
71-
composer test
72-
```
178+
TODO
73179

74180
## Changelog
75181

@@ -85,7 +191,7 @@ Please review [our security policy](../../security/policy) on how to report secu
85191

86192
## Credits
87193

88-
- [:author_name](https://github.com/:author_username)
194+
- [Leandro Pedrosa Rodrigues](https://github.com/pedrosalpr)
89195
- [All Contributors](../../contributors)
90196

91197
## License

0 commit comments

Comments
 (0)