alexcicioc / swagger-router
处理路由和请求/响应验证,这些在OpenApi规范中定义
v1.1.7
2020-02-18 08:06 UTC
Requires
- php: >=7.2.0
- ext-json: *
- guzzlehttp/psr7: ^1.5
- league/oauth2-server: ^7.4
README
Swagger Router 是一个库,在文档化的同时加速API开发。
它使用与 OpenAPI规范2.0 兼容的json规范文件,应该支持大多数功能。如果您发现缺少某些功能,请随时打开一个pull request或问题。
通过composer安装
composer require alexcicioc/swagger-router
使用swagger-router引导API
使用swagger定义端点
您需要在使用swagger规范中定义您的API端点。这里有一个简单的示例您可以使用(为了可读性,它是yaml格式的,但应该转换为json)
建议:您可以使用 Swagger Editor 安全地修改规范,然后点击文件菜单并“转换并保存到JSON”。
swagger: '2.0' info: version: 0.0.1 title: Courses API basePath: /api schemes: - http - https consumes: - application/json produces: - application/json paths: /courses: x-swagger-router-controller: Courses # used to route to the php controller class get: description: Returns a list of courses operationId: getCourses # used to route to the php controller method parameters: - $ref: '#/parameters/limitQuery' - $ref: '#/parameters/startIndexQuery' responses: '200': description: Success schema: $ref: '#/definitions/CourseList' default: description: Error schema: $ref: '#/definitions/ErrorResponse' '/courses/{courseId}': x-swagger-router-controller: Courses get: description: Returns a course operationId: getCourse # used to route to the php controller method parameters: - $ref: '#/parameters/courseIdPath' responses: '200': description: Success schema: $ref: '#/definitions/Course' '404': description: Not Found default: description: Error schema: $ref: '#/definitions/ErrorResponse' definitions: CourseList: properties: results: type: array items: $ref: '#/definitions/Course' required: - results Course: properties: id: description: Course id type: integer minimum: 1 title: description: Course title type: string maxLength: 255 shortDescription: description: Short description type: string maxLength: 255 longDescription: description: Long description type: string status: description: Course status type: string enum: - not-started - in-progress - complete default: not-started required: - id - title - shortDescription - longDescription - status ErrorResponse: required: - message properties: message: description: Error Message type: string parameters: courseIdPath: in: path name: courseId type: integer minimum: 1 required: true limitQuery: in: query name: limit type: integer default: 10 startIndexQuery: in: query name: startIndex type: integer default: 0
重定向请求
您需要将所有内容重定向到index.php。如果您使用Apache,可以将以下内容添加到您的 .htaccess 文件中
RewriteEngine on
RewriteRule ^(.*)$ index.php [NC,L,QSA]
使用swagger-router引导应用
在index.php中,您必须构建SwaggerRouter实例。您可以使用此示例
try { $app = new SwaggerRouter(); // Validates and extracts the information from your swagger spec $app->use(new SpecParser('/app/swagger.json')); # Path to your spec // Optional - Handles the /swagger endpoint that exposes the spec to frontend apps $app->use(new SwaggerRawHandler()); // Validates the called route, http method and content type $app->use(new RouteValidator()); // Handles extracting the parameters from the request and formatting them $app->use(new ParamsHandler()); // Optional - Validates the OAuth2 token given in the Authorization header $app->use(new OAuth(AuthorizationFactory::makeResourceServer())); // Optional - Handles validating the request parameters $app->use(new RequestValidator()); // Routes the request to it's specific controller (given by x-swagger-router-controller) $app->use(new Router('\App\Api\Controllers')); # Controllers namespace (must be PSR-4 compliant) // Handles formatting the response $app->use(new ResponseHandler()); // Optional - Handles validating the response $app->use(new ResponseValidator()); $swaggerRequest = SwaggerRequest::fromGlobals(); // extends PSR-7 ServerRequest $swaggerResponse = new SwaggerResponse(); // extends PSR-7 Response $response = $app($swaggerRequest, $swaggerResponse); $response->send(); } catch (HttpException $e) { (new SwaggerResponse()) ->withStatus($e->getCode()) ->body((object)['message' => $e->getMessage()]) ->send(); }
创建控制器
之前在规范中我们添加了这些行
x-swagger-router-controller: Courses
operationId: getCourses
这告诉swagger-router搜索Courses
控制器并调用getCourses
方法
namespace App\Api\Controllers; use Alexcicioc\SwaggerRouter\SwaggerRequest; use Alexcicioc\SwaggerRouter\SwaggerResponse; class Courses { public function getCourses(SwaggerRequest $request, SwaggerResponse $response): SwaggerResponse { $filters = $request->getParam('technology'); $limit = $request->getParam('limit'); $startIndex = $request->getParam('startIndex'); $results = []; // do db stuff here return $response ->withStatus(200) ->body((object)['results' => $results]); } public function getCourse(SwaggerRequest $request, SwaggerResponse $response): SwaggerResponse { $courseId = $request->getParam('courseId'); $course = new \stdClass(); $course->id = $courseId; // db stuff here return $response ->withStatus(200) ->body($course); } }
示例规范
https://github.com/alexcicioc/swagger-router/blob/master/sample-spec.json
Laravel 兼容性
Swagger Router的中间件目前与Laravel不兼容,但有一个解决方案。
这是一个示例Laravel中间件,它调用swagger router(未经适当测试,可能会有一些副作用)
<?php namespace App\Http\Middleware; use Alexcicioc\SwaggerRouter\Exceptions\HttpException; use Alexcicioc\SwaggerRouter\Middlewares\ParamsHandler; use Alexcicioc\SwaggerRouter\Middlewares\RequestValidator; use Alexcicioc\SwaggerRouter\Middlewares\ResponseHandler; use Alexcicioc\SwaggerRouter\Middlewares\ResponseValidator; use Alexcicioc\SwaggerRouter\Middlewares\Router; use Alexcicioc\SwaggerRouter\Middlewares\RouteValidator; use Alexcicioc\SwaggerRouter\Middlewares\SpecParser; use Alexcicioc\SwaggerRouter\Middlewares\SwaggerRawHandler; use Alexcicioc\SwaggerRouter\SwaggerRequest; use Alexcicioc\SwaggerRouter\SwaggerResponse; use Alexcicioc\SwaggerRouter\SwaggerRouter; use Closure; use Illuminate\Http\Request; class LaravelSwaggerRouter { public function handle(Request $request, Closure $next) { try { $app = new SwaggerRouter(); // Validates and extracts the information from your swagger spec $app->use(new SpecParser('/var/www/php/specs/spec.json')); # Path to your spec // Optional - Handles the /swagger endpoint that exposes the spec to frontend apps $app->use(new SwaggerRawHandler()); // Validates the called route, http method and content type $app->use(new RouteValidator()); // Handles extracting the parameters from the request and formatting them $app->use(new ParamsHandler()); // Optional - Handles validating the request parameters $app->use(new RequestValidator()); // Routes the request to it's specific controller (given by x-swagger-router-controller) $app->use(new Router('\App\Http\Controllers')); # Controllers namespace (must be PSR-4 compliant) // Handles formatting the response $app->use(new ResponseHandler()); // Optional - Handles validating the response $app->use(new ResponseValidator()); $swaggerRequest = SwaggerRequest::fromGlobals(); $swaggerResponse = new SwaggerResponse(); // extends PSR-7 Response $response = $app($swaggerRequest, $swaggerResponse); return response()->json($response->rawBody, $response->getStatusCode(), $response->getHeaders()); } catch (HttpException $e) { return response()->json((object)['message' => $e->getMessage()], $e->getCode()); } } }