mdwheele/laravel-openapi

0.1.0 2019-09-09 20:21 UTC

This package is auto-updated.

Last update: 2024-09-17 02:20:49 UTC


README

Latest Version on Packagist PHP from Packagist Total Downloads CircleCI

此包允许您为Laravel应用程序创建单个规范,该规范将注册路由并验证API接收的所有请求以及您生成的所有响应。

在PHP中使用OpenAPI的开发体验感觉是断裂的...

  • 我可以更新我的OpenAPI规范,而不会对实际实现产生影响,留下了一些偏差的空间。
  • 我可以尝试使用流程和自定义工具将它们粘合在一起,但我感觉我像是在把互联网的9,001个部分粘合在一起,每个项目都不同。我宁愿别人来做这项工作。
  • 文档生成器是 AMAZING 的,但如果没有任何东西可以阻止实现从文档中偏离,那么它有意义吗?
  • 用于验证JSON Schema的工具很棒,但返回的错误消息对于初学者来说很难理解,而且并不总是明显。

此包旨在创建一个积极的开发者体验,其中您真正有一个 单一的数据源,即您的OpenAPI规范。从这一点出发,该包将自动使用Laravel注册路由。此外,它将为这些路由附加一个 中间件,该中间件将验证所有传入的请求和从您的控制器生成的所有响应。当包检测到实现和规范之间的不匹配时,您将获得一个 有帮助 的错误消息,该消息提示您 下一步该做什么

安装

您可以通过Composer安装此包。

composer require mdwheele/laravel-openapi

可选地,您可以使用以下命令发布此包的配置文件

php artisan vendor:public --provider="Mdwheele\OpenApi\OpenApiServiceProvider"

以下配置文件将发布到 config/openapi.php

<?php

return [

    /*
     * The path to your OpenApi specification root document.
     */
    'path' => env('OPENAPI_PATH'),

    /*
     * Whether or not to validate response schemas. You may want to
     * enable this in development and disable in production. Do as you
     * wish!
     */
    'validate_responses' => env('OPENAPI_VALIDATE_RESPONSES', true)

];

使用

OPENAPI_PATH 配置为指向您的顶级规范。该包将解析您的OpenAPI规范以创建适当的路由并附加 ValidateOpenApi 中间件。该中间件验证所有传入到您的API的请求以及从您的控制器生成的所有响应。如果中间件遇到验证错误,它将抛出 OpenApiException,该异常将包含一个总结错误消息以及描述错误的详细信息(尽可能详细)。

将此纳入您的常规异常处理程序是个好主意,如下所示

class Handler extends Exception Handler
{
    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
        // This is only an example. You can format this however you 
        // wish. The point is that the library gives you easy access to 
        // "what went wrong" so you can react accordingly.
        if ($exception instanceof OpenApiException) {
            return response()->json([
                'message' => $exception->getMessage(),
                'errors' => $exception->getErrors(),
            ], 400);
        }

        return parent::render($request, $exception);
    }
}

当您生成不符合您指定的OpenApi模式的响应时,您将得到以下内容

{
  "message": "The response from CoreFeaturesController@healthCheck does not match your OpenAPI specification.",
  "errors": [
    "The [status] property must be one of [ok, warning, critical].",
    "The [updates[0].timestamp] property is missing. It must be included.",
    "The property unsupported is not defined and the definition for [updates[0]] does not allow additional properties."
  ]
}

作为进一步示例,请查看以下API规范。

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Your Application
servers:
  - url: https://localhost/api
paths:
  /pets:
    get:
      summary: List all pets
      operationId: App\Http\Controllers\PetsController@index
      responses:
        '200':
          description: An array of Pets.
          content:
            application/json:
              schema:
                type: array
                items: 
                  $ref: '#/components/schemas/Pet'
components:
  schemas:
    Pet:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string

此规范说明将在 https://localhost/api/pets 有一个端点,它可以接收一个 GET 请求,并且只返回带有 200 状态码的响应。那些成功的响应将返回包含JavaScript对象的 application/json,这些对象必须同时具有一个 id(这是一个 integer)和一个 name(可以是任何字符串)。

以下任何情况都会触发一个包含有关如何解决您的实现与您设计的OpenAPI规范之间的不匹配的额外信息的 OpenApiException

  • 如果您从 /api/pets 返回 403 响应,您将得到一个异常,解释说没有指定 403 的响应,也没有 default 处理程序。
  • 如果您返回除了 application/json 之外的内容,您将得到一个类似的异常,解释了可以返回的可接受的媒体类型。
  • 如果你返回使用基于字符串的 id 的 JavaScript 对象(例如 id: 'foo'),你将被告知你控制器生成的响应与指定的 JSON Schema 不匹配。此外,你还将得到一些关于具体哪里出错的提示以及一些解决方法的建议。

注意!

🔇 观点警报 ...并且请随意保留一粒盐。

就像过度详细测试可能会让你感到不舒服一样,过度详细地指定 API 也会让你陷入阻力分析和分析瘫痪。当你使用 JSON Schema 指定请求体、参数和响应时,请务必理解,你是在指定有效的 HTTP 消息,而不一定是系统中每个业务规则。

例如,我见过很多人陷入“但是 @mdwheele!我需要具有条件响应,因为当 X 发生时,我需要一个响应。但是当 Y 发生时,我需要一个完全不同的响应。”的困境。我对这个问题的建议是编写测试😀。这个库为你做的是,让你有信心不必编写大量的结构化测试,只是为了确保一切都在顶层的 data 封装下;filter 可以作为查询参数等。

另一种思考方式是“表单验证”和“业务不变量”之间的区别。很多时候,它们确实有重叠,但目标不同。表单验证(或 OpenAPI 规范验证)说“我有有效的 HTTP 消息吗?”而业务规则则更为微妙(例如,“这个用户是否有资格创建总价值超过 5000 美元的采购订单?”)。

路线图

  • 继续改进错误消息,使其尽可能有用。在此期间,使用该软件包,如果对如何响应错误消息不清楚,提交为错误
  • 添加更多的规范示例,以确保我们能够覆盖尽可能多的使用案例。
  • 改进框架集成错误处理。

测试

composer test

贡献

有关详细信息,请参阅 CONTRIBUTING

安全性

如果你发现任何安全相关的问题,请通过电子邮件 mdwheele@gmail.com 而不是使用问题跟踪器。

鸣谢

许可证

MIT 许可证 (MIT)。有关更多信息,请参阅 许可证文件