700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > laravel dingo/api 笔记

laravel dingo/api 笔记

时间:2022-10-10 09:03:01

相关推荐

laravel dingo/api 笔记

使用 Laravel 开发 API,参考了网上一些资料,laravel 默认已经支持了 API 开发,但是因为都没有了解过,打算尝试使用 Dingo APIgithub 地址:/dingo/apilaravel-china 中文文档:https://laravel-/docs/dingo-api/2.0.0文档写的非常详细,翻译的也非常好,但是需要仔细品读,另外 Dingo API 中使用到了其他两个技术,也需要了解下。之前已经写过笔记了,可参考:fractal - /beyond__devil/article/details/83870176jwt-auth - /beyond__devil/article/details/83827075这里简单挑几个重点写下:1.安装composer require dingo/api发布配置php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"FacadesDingo\Api\Facade\APIDingo\Api\Facade\Route2.配置信息3.创建端点(在 API 中,路由一般叫做端点)1)引用 Dingo API$api = app('Dingo\Api\Routing\Router');2)设置版本分组// 单个分组$api->version('v1', function($api){})// 多个分组$api->version(['v1', 'v2'], function($api){})// 第二个参数,还可以传递一个 『属性数组』$api->version(['v1', 'v2'], ['middleware' => 'foo'], function($api){})注意:属性数组,是旧版的 Laravel,5.7 版本有些可能不支持// 其他的和 laravel 的路由没有太大的区分(旧版,新版链式调用不支持)$api->version('v1', function($api){$api->group(['middleware' => 'bar'], function($api){...});})3)创建端点(之前大概看了点源码,忘记了,下面是之前笔记的)group() - 路由分组domain() - 子域名路由namespace() - 命名空间prefix() - 前缀name() - 命名前缀,是 as 的别名as() - 命名前缀middle() - 中间件where() - 参数的正则约束/*5.7 版本,可以使用这些方法,之前的版本,没有这些方法,使用的是:group(['prefix' => '', 'namespace' => '', ...], function(){});*/4)命名路由 & 生成路由$api->get('users/{id}', ['as' => 'users.index', 'uses' => 'Api\V1\UserController@show']);app('Dingo\Api\Routing\UrlGenerator')->version('v1')->route('users.index');5)命令行中查看路由php artisan api::routes注意:Laravel 5.7版本,routes/api.php 默认就具备中间件,我们需考虑使用 'Dingo API' 还是 'Laravel 系统默认'app/Providers/RouteServiceProvider.php Route::prefix('api')->middleware('api')->namespace($this->namespace)->group(base_path('routes/api.php'));注意:如果采用 Ding API,我们可能得取消这里默认的 prefix、middleware、namespace4.响应响应生成器,需要使用 'Dingo\Api\Routing\Helpers' trait。我们的 API 控制器基本都要使用它,所以创建一个 『基类控制器』php artisan make:controller Api/Controller<?phpnamespace App\Http\Controllers\Api;use Illuminate\Http\Request;use Dingo\Api\Routing\Helpers;use App\Http\Controllers\Controller as BaseController;class Controller extends BaseController{use Helpers;}关于响应生成器,文档写的很详细,上次可能看了下源码,总结了下,基本和文档一致。参考源码:Dingo\Api\Http\Response\Factory1)响应数组$user = User::findOrFail($id);$this->response->array($user->toArray());// 估计只能是数组// 查看源码:// array 时,会响应 $parameters[0] //『new Response($parameters[0])』2)响应一个元素$user = User::findOrFail($id);$this->response->item($user, new UserTransformer)3)响应一个元素集合$users = User::all();$this->response->collection($user, new UserTransformer)4)分页响应$users = User::paginate(25);$this->response->paginator($user, new UserTransformer)5)无内容响应$this->response->noContent();6)创建了资源的响应$this->response->created($location = null, $content = null);location - 会在 header 添加 Location 头部content - 响应内容7)accepted() - 同 created() 一样,created() 返回 201,accepted() 返回 2028)自定义错误内容和状态码error($message, $statusCode)9)其他调用 error() 的便捷方法errorNotFound() - 404errorBadRequest() - 400errorForbidden() - 403errorInternal() - 500errorUnauthorized() - 401errorMethodNotAllowed() - 40510)添加额外的头信息->withHeader('X-Foo', 'Bar')11)添加 Meta 信息->addMeta('foo', 'bar')->addMeta(xx, yy)->setMeta($meta)12)设置响应状态码->setStatusCode(200)事件:返回响应之前,会转换响应,如果响应的变化有更多的控制,可以使用以下2个事件ResponseWasMorphedResponseIsMorphing5.异常处理API 的开发过程中,对于异常,我们采用直接 throw,然后统一由 Dingo API 来捕获,统一处理Symfony 内置的异常Dingo API 内置的资源异常自定义异常继承 Symfony\Component\HttpKernel\Exception\HttpException或实现 Symfony\Component\HttpKernel\Exception\HttpExceptionInterface自定义异常响应app('Dingo\Api\Exception\Handler')->register(function (Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException $exception) {return Response::make(['error' => 'Hey, 你这是要干嘛!?'], 401);});表单请求定义基础的 API 表单请求类,验证失败,将抛出:Dingo\Api\Exception\ValidationHttpExceptionDingo API 默认的错误格式'errorFormat' => ['message' => ':message','errors' => ':errors','code' => ':code','status_code' => ':status_code','debug' => ':debug',],6.Transformers使用 transformers 有 2 种方法:1>为一个指定的类注册一个 transformer,直接从路由中返回这个类,并且通过 transformer 自动运行app('Dingo\Api\Transformer\Factory')->register('User', 'UserTransformer');2>使用响应生成器FractalFractal 是 Dingo API 使用的默认转换层自动关系预加载更多配置定义嵌入关系时,要自定义 'include' 关键词和 '分隔符',在 'service provider' 或 '启动文件' 中,手动实例化 'Dingo\Api\Transformer\Adapter\Fractal'$this->app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {// 这里是 'include' 和 ','return new Dingo\Api\Transformer\Adapter\Fractal(new League\Fractal\Manager, 'include', ',');});响应生成器的高级用法响应生成器的 item()、collection() 和 paginator() 方法,接受额外参数,进一步自定义 Fractal第三个参数 - 资源键return $this->item($user, new UserTransformer, ['key' => 'user']);第四个参数 - 回调函数return $this->collection($users, new UserTransformer, [], function ($resource, $fractal) {$resource->setCursor($cursor);});回调函数有 2 个参数:第一个参数:League\Fractal\Resource\Item 或 League\Fractal\Resource\Collection 实例第二个参数:League\Fractal\Manager 实例不使用 '第三个参数',也可以省略,直接传递 '第四个参数' 回调函数自定义转换层7.API 认证配置身份验证提供者内置 3 个身份验证提供者:HTTP Basic - Dingo\Api\Auth\Provider\BasicJSON Web Tokens - Dingo\Api\Auth\Provider\JWTOAuth 2.0 - Dingo\Api\Auth\Provider\OAuth2默认仅在配置文件中,启用 HTTP 基本身份验证HTTP 基本验证服务提供者使用 laravel 内置的默认基本身份验证。需要在 '配置文件' 或 '引导文件' 配置此服务提供者app('Dingo\Api\Auth\Auth')->extend('basic', function ($app) {return new Dingo\Api\Auth\Provider\Basic($app['auth'], 'email');});JSON Web Tokens(JWT)使用 tymon/jwt-auth 包在 '配置文件' 或 '引导文件' 中配置该服务提供者config.php'auth' => ['jwt' => 'Dingo\Api\Auth\Provider\JWT',],app('Dingo\Api\Auth\Auth')->extend('jwt', function ($app) {return new Dingo\Api\Auth\Provider\JWT($app['Tymon\JWTAuth\JWTAuth']);});OAuth 2.0使用 league/oauth2-server 或 lucadegasperi/oauth2-server-laravel 包需要配置 'provider server - 服务提供者' 或 'bootstrap - 引导文件'(包没有给我们提供 服务提供者,而 basic 和 jwt 都有默认的服务提供者,应该是这样...)同时,应该还需要配置 config.php 的 auth自定义身份验证保护级别可以使用 'api.auth' 中间件来验证// 某个版本路由$api->version(['middleware' => 'api.auth'], function(){});// 路由组$api->group( ['middleware' => 'api.auth'], function(){});// 单个路由$api->get('user', ['middleware' => 'api.auth'], function(){});控制器中$this->middleware('api.auth', ['only' => ['index']]);只允许特定的身份验证提供者$api->version(['middleware' => 'api.auth', 'providers' => ['basic', 'oauth']], function(){});检索经过身份验证的用户$user = app('Dingo\Api\Auth\Auth')->user();如果控制器中,使用了 'Dingo\Api\Routing\Helpers',可以使用 $this->auth 属性use Dingo\Api\Routing\Helpers;// 引入 traitclass UserController extends Controller{use Helpers;// 使用 traitpublic function index(){$user = $this->auth->user();return $user;}}不通过中间件来验证,需要手动在需要的地方进行验证if( !app('Dingo\Api\Auth\Auth')->user()){return '用户未验证!';}8.访问节流限制(rate limiting)改变节流限速的 key默认是 "客户端IP",通过 $request->getClientIp() 获取。我们可以自定义:app('Dingo\Api\Http\RateLimit\Handler')->setRateLimiter(function ($app, $request) {return $app['example']->getRateLimiterKey();});回调函数的 2 个参数是:$app - Ioc 容器$request - 请求实例启用节流限速使用 'api.throttle' 中间件支持,额外的 2 个选项:'middleware' => 'api.throttle', 'limit' => 100, 'expires' => 5limit - 限制次数expires - 过期时间自定义阀门(throttle)继承 Dingo\Api\Contract\Http\RateLimit\Throttle,定义一个 match() 方法,返回 true | falseuse Illuminate\Container\Container;use Dingo\Api\Http\RateLimit\Throttle\Throttle;class CustomThrottle extends Throttle{public function match(Container $app){// 在这里执行一些逻辑并根据是否返回 true 或 false// 你的条件与阀门匹配。}}注册阀门api.php'throttling' => ['custom' => new CustomThrottle(['limit' => 200, 'expires' => 10])]9.内部调用API 都是外部调用的,但是如果内部某个方法内,也想调用 API 的结果,这样可复用代码// 构建一个分发器$dispatcher = app('Dingo\Api\Dispatcher');// 发起内部请求$users = $dispatcher->get('api/users');控制器中,也可使用 'Dingo\Api\Routing\Helpers' traituse Dingo\Api\Routing\Helpers;// 引用 traitclass HomeController extends Controller{use Helpers;// 使用 traitpublic function index(){$users = $this->api->get('users');// 调用内部请求return view('index')->with('users', $users);}}发送数据$dispatcher->with(['name' => 'Jason', 'location' => 'Australia'])->post('users');或$dispatcher->post('users', ['name' => 'Jason', 'location' => 'Australia']);指定版本的 API$dispatcher->version('v2')->get('users');指定的域名$dispatcher->on('')->get('users');上传附件1>Symfony\Component\HttpFoundation\File\UploadedFile 实例数组$dispatcher->attach(Input::files())->post('photos');2>文件路径数组,数组 key 是文件的下标$dispatcher->attach(['photo' => 'photos/me.jpg'])->post('photos');3>文件路径相关的元数据数组(上传时,不会再计算文件 mime 类型和文件大小)dispatcher->attach(['photo' => ['path' => 'photos/me.jpg','mime' => 'image/jpeg','size' => '49430']])->post('photos');发送 JSON 数据$data = ['name' => 'bill', 'password' => 12345];$dispatcher->json($data)->post('users');注意:如果 $data 是一个数组,将会自动被转换为 json。这个请求的 Content-Type 被设置为 application/json模拟认证用户当我们请求的端点(路由),需要用户认证通过后,才可进行处理,模拟用户任何后续请求都将视为同一用户$dispatcher->be(auth()->user())->get('posts');只为给定的用户模拟一次请求$dispatcher->be(auth()->user())->once()->get('posts');获取原始返回对象// 默认的 API 请求,返回的数据是经过预先转换、格式化$response = $dispatcher->get('users');// 要想获取原始查询的数据,添加 raw()$response = $dispatcher->raw()->get('users');异常处理内部调用的 API,会抛出异常,我们如果想处理异常,需要自己捕获。捕获的异常类需要和抛出的异常类一致10.OAuth 2.0 认证Scopes11.请求你的 API使用 Postman 使用 CURLcurl -v -H "Accept: application/vnd.YOUR_SUBTYPE.v1+json" http://example.app/users12.API 文档资源/*** 用户资源标识** @Resource("Users", uri="/users")*/行为@Get、@Post、@Put、@Patch、@Delete@Versions@Request@Response@Transaction@Parameters13.命令行工具1>生成 API 路由列表php artisan api:routesphp artisan api:routes --versions v1php artisan api:routes --scopes read_user_data --scopes write_user_data2>缓存 API 路由,同时缓存主路由。php artisan api:cache切记:不要执行 laravel 的 route:cache,这样只会缓存主路由,不会缓存 Dingo API 的路由3>根据标准注释,生成 API 文档php artisan api:docsphp artisan api:docs --name Example --use-version v2 --output-file /path/to/documentation.mdphp artisan api:docs --name Example --use-version v2 > /path/to/documentation.md // 或使用 '>' 标准输出重定向

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。