253 lines
10 KiB
PHP
253 lines
10 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\File;
|
|
use Symfony\Component\Yaml\Yaml;
|
|
|
|
class GenerateSwagger extends Command
|
|
{
|
|
protected $signature = 'swagger:generate';
|
|
protected $description = 'Generate OpenAPI specification for the API';
|
|
|
|
public function handle(): int
|
|
{
|
|
$this->info('Generating OpenAPI specification...');
|
|
|
|
$outputDir = public_path('docs');
|
|
if (!File::exists($outputDir)) {
|
|
File::makeDirectory($outputDir, 0755, true);
|
|
}
|
|
|
|
$spec = $this->generateSpec();
|
|
$yaml = Yaml::dump($spec, 4, 2);
|
|
|
|
File::put($outputDir . '/openapi.yaml', $yaml);
|
|
$this->info('OpenAPI specification saved to public/docs/openapi.yaml');
|
|
|
|
return Command::SUCCESS;
|
|
}
|
|
|
|
protected function generateSpec(): array
|
|
{
|
|
$appUrl = config('app.url', 'http://localhost');
|
|
|
|
return [
|
|
'openapi' => '3.0.0',
|
|
'info' => [
|
|
'title' => config('app.name', 'Laravel API'),
|
|
'description' => 'API Documentation',
|
|
'version' => '1.0.0',
|
|
],
|
|
'servers' => [
|
|
['url' => $appUrl, 'description' => 'Local server'],
|
|
],
|
|
'paths' => $this->generatePaths(),
|
|
'components' => [
|
|
'securitySchemes' => [
|
|
'bearerAuth' => [
|
|
'type' => 'http',
|
|
'scheme' => 'bearer',
|
|
'bearerFormat' => 'JWT',
|
|
],
|
|
],
|
|
'schemas' => $this->generateSchemas(),
|
|
],
|
|
];
|
|
}
|
|
|
|
protected function generatePaths(): array
|
|
{
|
|
return [
|
|
'/api/register' => [
|
|
'post' => [
|
|
'tags' => ['Auth'],
|
|
'summary' => 'Register a new user',
|
|
'requestBody' => [
|
|
'required' => true,
|
|
'content' => [
|
|
'application/json' => [
|
|
'schema' => [
|
|
'type' => 'object',
|
|
'required' => ['name', 'email', 'password', 'password_confirmation'],
|
|
'properties' => [
|
|
'name' => ['type' => 'string', 'example' => 'John Doe'],
|
|
'email' => ['type' => 'string', 'format' => 'email', 'example' => 'john@example.com'],
|
|
'password' => ['type' => 'string', 'format' => 'password', 'example' => 'password123'],
|
|
'password_confirmation' => ['type' => 'string', 'format' => 'password', 'example' => 'password123'],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
'responses' => [
|
|
'201' => ['description' => 'User registered successfully'],
|
|
'422' => ['description' => 'Validation error'],
|
|
],
|
|
],
|
|
],
|
|
'/api/login' => [
|
|
'post' => [
|
|
'tags' => ['Auth'],
|
|
'summary' => 'Login user',
|
|
'requestBody' => [
|
|
'required' => true,
|
|
'content' => [
|
|
'application/json' => [
|
|
'schema' => [
|
|
'type' => 'object',
|
|
'required' => ['email', 'password'],
|
|
'properties' => [
|
|
'email' => ['type' => 'string', 'format' => 'email', 'example' => 'john@example.com'],
|
|
'password' => ['type' => 'string', 'format' => 'password', 'example' => 'password123'],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
'responses' => [
|
|
'200' => ['description' => 'Login successful'],
|
|
'401' => ['description' => 'Invalid credentials'],
|
|
],
|
|
],
|
|
],
|
|
'/api/logout' => [
|
|
'post' => [
|
|
'tags' => ['Auth'],
|
|
'summary' => 'Logout user',
|
|
'security' => [['bearerAuth' => []]],
|
|
'responses' => [
|
|
'200' => ['description' => 'Logged out successfully'],
|
|
],
|
|
],
|
|
],
|
|
'/api/user' => [
|
|
'get' => [
|
|
'tags' => ['Auth'],
|
|
'summary' => 'Get authenticated user',
|
|
'security' => [['bearerAuth' => []]],
|
|
'responses' => [
|
|
'200' => ['description' => 'User data'],
|
|
],
|
|
],
|
|
],
|
|
'/api/posts' => [
|
|
'get' => [
|
|
'tags' => ['Posts'],
|
|
'summary' => 'Get all posts',
|
|
'security' => [['bearerAuth' => []]],
|
|
'responses' => [
|
|
'200' => ['description' => 'List of posts'],
|
|
],
|
|
],
|
|
'post' => [
|
|
'tags' => ['Posts'],
|
|
'summary' => 'Create a new post',
|
|
'security' => [['bearerAuth' => []]],
|
|
'requestBody' => [
|
|
'required' => true,
|
|
'content' => [
|
|
'application/json' => [
|
|
'schema' => [
|
|
'type' => 'object',
|
|
'required' => ['title', 'content'],
|
|
'properties' => [
|
|
'title' => ['type' => 'string', 'example' => 'My Post Title'],
|
|
'content' => ['type' => 'string', 'example' => 'Post content here...'],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
'responses' => [
|
|
'201' => ['description' => 'Post created successfully'],
|
|
'422' => ['description' => 'Validation error'],
|
|
],
|
|
],
|
|
],
|
|
'/api/posts/{id}' => [
|
|
'get' => [
|
|
'tags' => ['Posts'],
|
|
'summary' => 'Get a post',
|
|
'security' => [['bearerAuth' => []]],
|
|
'parameters' => [
|
|
['name' => 'id', 'in' => 'path', 'required' => true, 'schema' => ['type' => 'integer']],
|
|
],
|
|
'responses' => [
|
|
'200' => ['description' => 'Post data'],
|
|
'404' => ['description' => 'Post not found'],
|
|
],
|
|
],
|
|
'put' => [
|
|
'tags' => ['Posts'],
|
|
'summary' => 'Update a post',
|
|
'security' => [['bearerAuth' => []]],
|
|
'parameters' => [
|
|
['name' => 'id', 'in' => 'path', 'required' => true, 'schema' => ['type' => 'integer']],
|
|
],
|
|
'requestBody' => [
|
|
'required' => true,
|
|
'content' => [
|
|
'application/json' => [
|
|
'schema' => [
|
|
'type' => 'object',
|
|
'properties' => [
|
|
'title' => ['type' => 'string', 'example' => 'Updated Title'],
|
|
'content' => ['type' => 'string', 'example' => 'Updated content...'],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
'responses' => [
|
|
'200' => ['description' => 'Post updated successfully'],
|
|
'404' => ['description' => 'Post not found'],
|
|
'422' => ['description' => 'Validation error'],
|
|
],
|
|
],
|
|
'delete' => [
|
|
'tags' => ['Posts'],
|
|
'summary' => 'Delete a post',
|
|
'security' => [['bearerAuth' => []]],
|
|
'parameters' => [
|
|
['name' => 'id', 'in' => 'path', 'required' => true, 'schema' => ['type' => 'integer']],
|
|
],
|
|
'responses' => [
|
|
'200' => ['description' => 'Post deleted successfully'],
|
|
'404' => ['description' => 'Post not found'],
|
|
],
|
|
],
|
|
],
|
|
];
|
|
}
|
|
|
|
protected function generateSchemas(): array
|
|
{
|
|
return [
|
|
'User' => [
|
|
'type' => 'object',
|
|
'properties' => [
|
|
'id' => ['type' => 'integer'],
|
|
'name' => ['type' => 'string'],
|
|
'email' => ['type' => 'string', 'format' => 'email'],
|
|
'role' => ['type' => 'string'],
|
|
'created_at' => ['type' => 'string', 'format' => 'date-time'],
|
|
],
|
|
],
|
|
'Post' => [
|
|
'type' => 'object',
|
|
'properties' => [
|
|
'id' => ['type' => 'integer'],
|
|
'title' => ['type' => 'string'],
|
|
'content' => ['type' => 'string'],
|
|
'user_id' => ['type' => 'integer'],
|
|
'user' => ['$ref' => '#/components/schemas/User'],
|
|
'created_at' => ['type' => 'string', 'format' => 'date-time'],
|
|
'updated_at' => ['type' => 'string', 'format' => 'date-time'],
|
|
],
|
|
],
|
|
];
|
|
}
|
|
}
|