johnylemon/laravel-apidocs

Laravel API 文档生成工具

1.1.0 2020-12-10 22:57 UTC

This package is auto-updated.

Last update: 2024-09-11 07:26:31 UTC


README

GitHub Workflow Status GitHub tag (latest by date)

问题

我不喜欢编写大量的愚蠢注释,只是为了希望 API 文档能正确生成,而不出现无意义的错误。而且我并不是唯一的一个。 更多.

这个包以我喜欢的方式解决这个问题 - 通过编写 PHP 代码。

解决方案

这个包为 Laravel 路由添加了 apidocs 方法,您可以使用每天使用的代码定义路由定义。

这样您就可以

  • 重用、扩展和修改现有的 API 定义
  • 创建通用的端点定义,只需按需修改或创建子类
  • 定义多个示例
  • 定义多个样本响应
  • 定义和重用参数定义
  • 再次使控制器可读

img

入门

  1. 添加 johnylemon/laravel-apidocs 仓库
composer require johnylemon/laravel-apidocs
  1. 如果未自动注册,请注册 Johnylemon\Apidocs\Providers\ApidocsServiceProvider 提供者。

  2. 安装包。此命令将发布所有必需的资产。

php artisan apidocs:install
  1. 享受吧!

生成路由文档

这个包带有快速路由定义生成的命令。

php artisan apidocs:endpoint SampleEndpoint

全新的 SampleEndpoint 类将放置在 app\Apidocs\Endpoints 目录中。目标目录可以在您的 apidocs 配置文件中更改。

此类仅包含一个 describe 方法,您必须使用任何可用的方法来描述您的端点。例如:

<?php

namespace App\Apidocs\Endpoints;

use Johnylemon\Apidocs\Endpoints\Endpoint;
use Johnylemon\Apidocs\Facades\Param;

class SampleEndpoint extends Endpoint
{
    public function describe(): void
    {
        $this->title('List users')
            ->desc('Returns paginated list of users');
    }
}

如您所见,我们设置了标题和描述作为端点定义。每个 方法 都返回端点实例,因此您可以将它们链接起来。

端点可用方法

uri

设置 uri。在端点挂载时在幕后调用

$this->uri('/users');

method

设置端点方法。在端点挂载时在幕后调用

$this->method('POST');

group

将端点添加到特定的 。组必须事先定义。

$this->group('some-group-slug');

deprecated

将端点标记为已弃用。

$this->deprecated();

title

设置端点标题

$this->title('Create user resource');

description

设置端点描述

$this->description('This endpoint contains logic for creating user resources based on provided data');

desc

description 的别名

query

定义端点查询参数。见:参数

$this->query([
    'page' => Param::type('int')
])

params

定义端点路由参数。见:参数

$this->query([
    'page' => Param::type('int')
])

body

定义端点正文参数。见:参数

$this->query([
    'page' => Param::type('int')
])

头部

定义端点头部

$this->header('x-johnylemon', 'apidocs')

头部们

一次性定义多个端点头部

$this->headers([
    'x-johnylemon' => 'apidocs',
    'x-laravel' => 'framework'
])

示例

定义端点示例。可选地,您可以定义示例标题

$this->example([
    'name' => 'johnylemon',
    'web' => 'https://johnylemon.dev',
    'email' => 'hello@johnylemon.dev'
], 'Store user')

示例们

一次性定义多个端点示例

$this->examples([
    [
        'name' => 'johny',
        'web' => 'https://johnylemon.dev',
        'email' => 'hello@johnylemon.dev'
    ],
    [
        'name' => 'lemon',
        'web' => 'https://johnylemon.dev',
        'email' => 'hello@johnylemon.dev'
    ]
])

返回值

定义带有状态码的示例返回值。可选地,您还可以定义响应描述。

$this->returns(201, [
    'name' => 'johny',
    'web' => 'https://johnylemon.dev',
    'email' => 'hello@johnylemon.dev'
], 'User created')
->returns(401, [
    'status' => 'unauthorized',
], 'Auth issue');

您还可以使用如 returns201 (或任何其他状态码) 的方法

// calling this ...
$this->returns201([
    'name' => 'johny',
    'web' => 'https://johnylemon.dev',
    'email' => 'hello@johnylemon.dev'
], 'User created');

// ... is equivalent of this...

$this->returns(201, [
    'name' => 'johny',
    'web' => 'https://johnylemon.dev',
    'email' => 'hello@johnylemon.dev'
], 'User created')

端点定义用法

好的,您已经创建了第一个端点定义。现在,是时候将其用作一些真实路由定义了。

让我们假设您有以下路由

Route::get('api/users', [UsersController::class, 'index']);

如果您想将 App\Apidocs\Endpoints\SampleEndpoint 类用作第一个路由的定义,您只需这样做

use App\Apidocs\Endpoints\SampleEndpoint;

Route::get('api/users', [UsersController::class, 'index'])->apidocs(SampleEndpoint::class);

是的,就是这样!

现在,您唯一需要做的事情就是调用 php artisan apidocs:generate 命令,并访问 /apidocs 路由来查看其效果!

⚠️ 此包必须清除路由缓存以正确生成apidocs。 如果您在生产环境中使用路由缓存,请记住在 artisan apidocs:generate 命令之后调用 artisan route:cache

因为 apidocs 方法返回端点类,您可以在路由定义期间链式调用方法。例如,您可能希望将您的路由标记为已弃用

use App\Apidocs\Endpoints\SampleEndpoint;

Route::get('api/users', [UsersController::class, 'index'])->apidocs(SampleEndpoint::class)->deprecated();

因为 deprecated 方法也返回端点,因此您可以使用 其他端点方法

⚠️ 在调用 apidocs 方法后,您不能使用特定于路由的方法,例如,比如 name 方法。务必在调用所有框架特定于路由的方法之后调用 apidocs 方法。

资源路由

有时您会想使用 resourceapiResource 方法来创建大量的典型 CRUD 端点。为了指定这些端点的定义,您必须使用它们的名称

Route::resource('posts', PostsController::class)->apidocs([
    'posts.index' => PostsIndexEndpoint::class,
    'posts.store' => PostStoreEndpoint::class,
]);

如您所见,您可以省略不希望被记录的端点。

有时您可能使用 resourcesapiResources 方法来一次性创建大量的 CRUD。由于 Laravel 不提供任何方便的钩子,使用这种方式定义的路由(以及任何其他命名路由!)可以使用 apidocs 辅助程序进行记录

//
// your resoures
//
Route::resources([
    'users' => UsersController::class,
    'posts' => PostsController::class,
]);

//
// defining endpoints
//
apidocs([
    'posts.index'   => PostsIndexEndpoint::class,
    'posts.store'   => PostStoreEndpoint::class,
    'users.index'   => UsersIndexEndpoint::class,
    'users.store'   => UserStoreEndpoint::class,
    'users.destroy' => UserStoreEndpoint::class,
]);

如前所述,您可以省略不希望被记录的端点。

参数

一些路由包含路由参数,如 {user} 段。有时您还希望使用必需或可选的查询参数。例如,POSTPATCHPUT 路由几乎总是期望一些有效负载。

您可以使用 params 定义它们,并在描述端点时将它们作为数组传递给 querybodyparams 方法。

假设您的 index 路由(在前面展示的路由中)期望可选的 page 参数。

现在,您的定义应包含对 query 方法的额外调用,并带有可能的参数数组。之后,您的代码将看起来像这样

<?php

namespace App\Apidocs\Endpoints;

use Johnylemon\Apidocs\Endpoints\Endpoint;
use Johnylemon\Apidocs\Facades\Param;

class SampleEndpoint extends Endpoint
{
    public function describe(): void
    {
        $this->title('List users')
            ->desc('Returns paginated list of users')
            ->query([
                Param::int('page')->example(1)->default(1)->optional()
            ])
    }
}

请注意,我们没有通过数组键指定参数名称(page)。当您在类中定义参数名称时,这不是必需的。但当然,您可以用不同的方式定义它们

use Johnylemon\Apidocs\Facades\Param;

$this->query([

    // parameter name will be `page`
    Param::int('page')->example(1)->default(1)->optional()

    // same effect:
    'page' => Param::int('page')->example(1)->default(1)->optional()

    // same effect:
    'page' => Param::type('int')->example(1)->default(1)->optional()

    // this parameter will be named `page_number`
    'page_number' => Param::int('page')->example(1)->default(1)->optional()
])

如您所见,当参数名称在两个位置定义时,数组键将优先,这允许您创建可重用的 自定义参数

您可以以相同的方式定义路由参数和请求体参数。

可用方法

类型

定义参数类型

Param::type('int');

名称

定义参数名称

Param::name('username');

description

定义参数描述

Param::description('Unique username');

desc

description 的别名。参见 描述

必填

标记参数为必填

Param::required();

可选

标记参数为可选

Param::optional();

可能值

设置参数的可能值

Param::possible([10, 100, 1000]);

枚举

possible 的别名。参见 可能值

Param::enum([10, 100, 1000]);

默认值

设置参数默认值。

Param::default(42);

示例

设置参数示例。

Param::example(42);

示例

example 的别名。参见 示例

Param 类利用了魔法 __call 方法,并允许您通过使用以下方法之一一次性定义参数类型和名称:stringarraybooleanboolintegerint

use Johnylemon\Apidocs\Facades\Param;

$this->query([
    Param::string('slug'), // `slug` property, that should have `string` type
    Param::int('id'), // id `property`, that should have `int` type
    Param::array('roles'), // `roles` property, that should have `array` type
])

自定义参数

在处理不同的端点定义时,您可能会使用 page 或其他参数。因此,可能需要反复编写类似的内容,这可能会变得繁琐。

$this->query([
    Param::int('page')->example(1)->default(1)->optional()
]);

为了解决这个问题,您可以定义 PageParam,这样您就可以多次重用它而无需重复代码。

use App\Apidocs\Params\PageParam;

(...)

$this->query([
    PageParam::class
]);

创建自定义参数

可以通过键入以下内容创建自定义参数:

php artisan apidocs:param PageParam

新的参数类可以在 __construct 方法中定义。

<?php

namespace App\Apidocs\Params;

use Johnylemon\Apidocs\Params\Param;

class PageParam extends Param
{
    public function __construct()
    {
        $this->name('page')->type('int')->default(1)->eg(42)->optional();
    }
}

Apidocs 端点将被分组。如果没有指定组,将使用默认的 non-groupped 组。

您可以使用 Johnylemon\Apidocs\Facades\Apidocs 门面定义自己的组。

use Johnylemon\Apidocs\Facades\Apidocs;

Apidocs::defineGroup('users', 'Users', 'Manage users');
Apidocs::defineGroup('tickets', 'Tickets'); // Last parameter is optional

必须在注册路由之前定义组。 定义组的最理想位置是路由文件的开头。

命令

该软件包附带一些命令,这些命令将用于常见的任务。

测试

您可以使用以下命令运行测试:

vendor/bin/phpunit

许可证

MIT 许可证 (MIT)。有关详细信息,请参阅 LICENSE

联系

请访问 https://johnylemon.dev

下一步

  • 改进示例
  • 改进响应
  • 改进资源
  • 改进布局

johnylemon 用 ❤ 开发。