Skip to content

Commit 21eb4a2

Browse files
authored
Merge pull request #22 from Lomkit/feature/documentation
🚧 automatic documentation
2 parents 54e31d5 + cb41a0f commit 21eb4a2

33 files changed

+2903
-12
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ TODO
9797
## Roadmap for the end of bêta (Estimated delivery October 2023)
9898

9999
- Automatic documentation with extension possible
100-
- Refactor actions listing to --> Get resource informations (fields exposed / actions / etc ? regroupe all those possibilities)
101-
- Alias for includes / aggregates
100+
- Add tests for all commands !!!!
102101

103102
## Roadmap
104103

105104
- Metrics support
106105
- Refactor the response class
107106
- Plain text search using Laravel Scout
107+
- Alias for includes / aggregates

config/rest.php

Lines changed: 88 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,96 @@
2727
],
2828

2929
/*
30-
|--------------------------------------------------------------------------
31-
| Rest Authorizations
32-
|--------------------------------------------------------------------------
33-
|
34-
| This is the feature that automatically binds to policies to validate incoming requests.
35-
| Laravel Rest Api will validate each models searched / mutated / deleted to avoid leaks in your API.
36-
|
37-
*/
30+
|--------------------------------------------------------------------------
31+
| Rest Authorizations
32+
|--------------------------------------------------------------------------
33+
|
34+
| This is the feature that automatically binds to policies to validate incoming requests.
35+
| Laravel Rest Api will validate each models searched / mutated / deleted to avoid leaks in your API.
36+
|
37+
*/
3838

3939
'authorizations' => [
4040
'enabled' => true
4141
],
42+
43+
/*
44+
|--------------------------------------------------------------------------
45+
| Rest Documentation
46+
|--------------------------------------------------------------------------
47+
|
48+
| This is the feature that generates automatically your API documentation for you.
49+
| Laravel Rest Api will validate each models searched / mutated / deleted to avoid leaks in your API.
50+
| This feature is based on OpenApi, for more detail see: https://swagger.io/specification/
51+
|
52+
*/
53+
54+
'documentation' => [
55+
'routing' => [
56+
'enabled' => true,
57+
'domain' => null,
58+
'path' => '/api-documentation',
59+
'middlewares' => [
60+
'web'
61+
]
62+
],
63+
'info' => [
64+
'title' => config('app.name'),
65+
'summary' => 'This is my projet\'s documentation',
66+
'description' => 'Find out all about my projet\'s API',
67+
'termsOfService' => null, // (Optional) Url to terms of services
68+
'contact' => [
69+
'name' => 'My Company',
70+
'email' => 'email@company.com',
71+
'url' => 'https://company.com'
72+
],
73+
'license' => [
74+
'url' => null,
75+
'name' => 'Apache 2.0',
76+
'identifier' => 'Apache-2.0'
77+
],
78+
'version' => '1.0.0'
79+
],
80+
// See https://spec.openapis.org/oas/v3.1.0#server-object
81+
'servers' => [
82+
[
83+
'url' => '/', // Relative to current
84+
'description' => 'The current server'
85+
],
86+
// [
87+
// 'url' => '"https://my-server.com:{port}/{basePath}"',
88+
// 'description' => 'Production server',
89+
// 'variables' => [
90+
// 'port' => [
91+
// 'enum' => ['80', '443'],
92+
// 'default' => '443'
93+
// ],
94+
// 'basePath' => [
95+
// 'default' => 'v2',
96+
// 'enum' => ['v1', 'v2'],
97+
// ]
98+
// ]
99+
// ]
100+
],
101+
// See https://spec.openapis.org/oas/v3.1.0#security-scheme-object
102+
'security' => [
103+
// [
104+
// 'type' => 'http',
105+
// 'description' => 'description',
106+
// 'scheme' => 'Bearer',
107+
// 'bearerFormat' => 'JWT'
108+
// ],
109+
// [
110+
// 'type' => 'oauth2',
111+
// 'flows' => [
112+
// 'authorizationCode' => [
113+
// 'scopes' => ['write:pets'],
114+
// 'tokenUrl' => 'https://example.com/api/oauth/token',
115+
// 'authorizationUrl' => 'https://example.com/api/oauth/dialog',
116+
// 'refreshUrl' => 'https://example.com/api/oauth/refresh',
117+
// ]
118+
// ]
119+
// ]
120+
]
121+
],
42122
];

resources/views/index.blade.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<meta
7+
name="description"
8+
content="SwaggerUI"
9+
/>
10+
<title>SwaggerUI</title>
11+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.4.2/swagger-ui.css" />
12+
</head>
13+
<body>
14+
<div id="swagger-ui"></div>
15+
<script src="https://unpkg.com/swagger-ui-dist@5.4.2/swagger-ui-bundle.js" crossorigin></script>
16+
<script>
17+
window.onload = () => {
18+
window.ui = SwaggerUIBundle({
19+
url: '/vendor/rest/openapi.json',
20+
dom_id: '#swagger-ui',
21+
});
22+
};
23+
</script>
24+
</body>
25+
</html>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace Lomkit\Rest\Console\Commands;
4+
5+
use Illuminate\Console\Command;
6+
use Illuminate\Console\GeneratorCommand;
7+
use Illuminate\Contracts\Console\PromptsForMissingInput;
8+
use Illuminate\Database\Migrations\MigrationCreator;
9+
use Illuminate\Support\Composer;
10+
use Illuminate\Support\Str;
11+
use Lomkit\Rest\Console\ResolvesStubPath;
12+
use Lomkit\Rest\Documentation\Schemas\Contact;
13+
use Lomkit\Rest\Documentation\Schemas\Info;
14+
use Lomkit\Rest\Documentation\Schemas\License;
15+
use Lomkit\Rest\Documentation\Schemas\OpenAPI;
16+
use RuntimeException;
17+
18+
class DocumentationCommand extends GeneratorCommand implements PromptsForMissingInput
19+
{
20+
/**
21+
* The console command signature.
22+
*
23+
* @var string
24+
*/
25+
protected $signature = 'rest:documentation
26+
{--path= : The location where the documentation file should be created}';
27+
28+
/**
29+
* The console command description.
30+
*
31+
* @var string
32+
*/
33+
protected $description = 'Generate the documentation';
34+
35+
public function handle()
36+
{
37+
$openApi = (new OpenAPI)
38+
->generate();
39+
40+
$path = $this->getPath('openapi');
41+
42+
$this->makeDirectory($path);
43+
44+
$this->files->put(
45+
$path,
46+
json_encode($openApi->jsonSerialize())
47+
);
48+
}
49+
50+
/**
51+
* Get the documentation path.
52+
*
53+
* @param string $name
54+
* @return string
55+
*/
56+
protected function getPath($name)
57+
{
58+
return public_path('vendor/rest/'.$name.'.json');
59+
}
60+
61+
protected function getStub()
62+
{
63+
throw new RuntimeException('Should not be here');
64+
}
65+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
namespace Lomkit\Rest\Documentation\Schemas;
4+
5+
class Contact extends Schema
6+
{
7+
/**
8+
* The identifying name of the contact person/organization.
9+
* @var string
10+
*/
11+
protected string $name;
12+
13+
/**
14+
* The URL pointing to the contact information.
15+
* @var string
16+
*/
17+
protected string $url;
18+
19+
/**
20+
* The email address of the contact person/organization.
21+
* @var string
22+
*/
23+
protected string $email;
24+
25+
public function withName(string $name): Contact
26+
{
27+
$this->name = $name;
28+
return $this;
29+
}
30+
31+
public function name(): string
32+
{
33+
return $this->name;
34+
}
35+
36+
public function withUrl(string $url): Contact
37+
{
38+
$this->url = $url;
39+
return $this;
40+
}
41+
42+
public function url(): string
43+
{
44+
return $this->url;
45+
}
46+
47+
public function withEmail(string $email): Contact
48+
{
49+
$this->email = $email;
50+
return $this;
51+
}
52+
53+
public function email(): string
54+
{
55+
return $this->email;
56+
}
57+
58+
public function jsonSerialize(): mixed
59+
{
60+
return [
61+
'name' => $this->name(),
62+
'url' => $this->url(),
63+
'email' => $this->email()
64+
];
65+
}
66+
67+
public function generate(): Contact
68+
{
69+
return $this
70+
->withName(config('rest.documentation.info.contact.name'))
71+
->withEmail(config('rest.documentation.info.contact.email'))
72+
->withUrl(config('rest.documentation.info.contact.url'));
73+
}
74+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace Lomkit\Rest\Documentation\Schemas;
4+
5+
use Lomkit\Rest\Http\Controllers\Controller;
6+
7+
class Example extends Schema
8+
{
9+
/**
10+
* Value
11+
* @var string
12+
*/
13+
protected array $value;
14+
15+
public function jsonSerialize(): mixed
16+
{
17+
return $this->value();
18+
}
19+
20+
public function generate(): Example
21+
{
22+
return $this;
23+
}
24+
25+
public function withValue(array $value): Example
26+
{
27+
$this->value = $value;
28+
return $this;
29+
}
30+
31+
public function value(): array
32+
{
33+
return $this->value;
34+
}
35+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace Lomkit\Rest\Documentation\Schemas;
4+
5+
use Lomkit\Rest\Http\Controllers\Controller;
6+
7+
class Examples extends Schema
8+
{
9+
/**
10+
* Examples
11+
* @var array
12+
*/
13+
protected array $examples = [];
14+
15+
public function withExamples(array $examples): Examples
16+
{
17+
$this->examples = array_merge($this->examples, $examples);
18+
return $this;
19+
}
20+
21+
public function examples(): array
22+
{
23+
return $this->examples;
24+
}
25+
26+
public function jsonSerialize(): mixed
27+
{
28+
return collect($this->examples())->map->jsonSerialize()->toArray();
29+
}
30+
31+
public function generate(): Examples
32+
{
33+
return $this;
34+
}
35+
36+
public function generateDetail(Controller $controller): Examples
37+
{
38+
return $this
39+
->withExamples(
40+
[
41+
'application/json' => (new Example)
42+
->withExample(
43+
json_encode(
44+
['test1234' => 'OAZEOOEZAOEOAZ']
45+
)
46+
)
47+
]
48+
)
49+
->generate();
50+
}
51+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Lomkit\Rest\Documentation\Schemas;
4+
5+
class Header extends Parameter
6+
{
7+
public function withName(string $name): Parameter
8+
{
9+
throw new \RuntimeException('Name is forbidden on headers');
10+
}
11+
}

0 commit comments

Comments
 (0)