伽拉法诺 / lingo
简洁的REST抽象
Requires
- dusterio/laravel-plain-sqs: ^0.1.17
- guzzlehttp/guzzle: ~6.0
This package is auto-updated.
Last update: 2024-09-27 01:54:04 UTC
README
Lingo是一个为Laravel提供的包,它为任何REST服务提供了一层抽象。因此,可以将http通信的概念封装在更接近面向对象的设计中,从而提高开发者的体验。
安装
使用包管理器 composer 安装Lingo。
composer require galafeno/lingo
用法
使用命令 make:lingo
在您的应用程序中初始化一个新的Lingo。
php artisan make:lingo AwesomeApi --base_url=https://awesome.api/v1
该命令在 App\Lingos
文件夹中创建一个名为 AwesomeApiLingo
的类。
要建模API,您应该在 AwesomeApiLingo
类中的 sync
部分添加端点。
protected $sync = [ 'base_url' => 'https://awesome.api/v1', 'commands' => [ 'getMovie' => [ 'verb' => 'get', 'url' => "/movies/{:?}" ], ] ];
之后,您可以在应用程序中使用您的Lingo如下所示
$movie = Lingo::awesomeApi()->command('getMovie',1)->send(); echo $movie->name; // Batman v Superman: Dawn of Justice
command
方法应至少接受一个参数(命令名称)。在这种情况下,它接收了2个参数,因为 getMovie
命令有一个绑定值(用 {:?}
通配符标记)。
自定义头部
Lingo被设计来处理json数据类型,因此它将始终将 Content-Type: application/json
和 Accept: application/json
添加到默认头部。要定义其他头部,在您的Lingo类中创建一个 headers
属性。
protected $headers = [ 'DomainId' => 15, 'SafeMode' => 'Unguarded' ];
这将生成以下头部,用于每个请求
{ "Content-Type": "application/json", "Accept": "application/json", "DomainId": "15", "SafeMode": "Unguarded" }
您还可以在运行时定义额外的头部如下所示
Lingo::awesomeApi() ->command('getMovie',1) ->withHeaders(['Scope' => 'readOnly']) ->send();
查询参数
要定义查询参数,在您的Lingo类中创建一个 params
属性
protected $params = [ 'start' => '2020-02-02', 'end' => '2020-04-04' ];
这将插入以下查询参数到每个请求中
GET https://awesome.api/v1/movies/1?start=2020-02-02&end=2020-04-04
您还可以在运行时定义额外的查询参数如下所示
Lingo::awesomeApi() ->command('getMovie',1) ->withParams(['user_id' => 1]) ->send();
正文参数
要定义正文参数,在您的Lingo类中创建一个 data
属性
protected $data = [ 'username' => 'superuser', 'email' => 'superuser@super.user' ];
这将插入以下正文参数到每个请求中
POST https://awesome.api/v1/movies { "username": "superuser", "email": "superuser@super.user" }
您还可以在运行时定义额外的正文参数如下所示
Lingo::awesomeApi() ->command('getMovie',1) ->withData(['user_id' => 1]) ->send();
闭包命令
通常您应该将Lingo用作将端点映射到命令的方式。但是,使用闭包命令语法,您可以触发一个函数而不是真实的HTTP请求。这是一个方便的方式来添加有关您的API的元数据。要这样做,在您的命令配置中使用关键字function。然后只需在您的Lingo类中添加引用的函数。
'commands' => [ ... 'list' => [ 'function' => 'getCommandList' ], ... ]; ... protected function getCommandList($bindings) { foreach ($this->sync['commands'] as $command) { if ( isset($command['verb']) && isset($command['url']) ){ echo strtoupper($command['verb']) . " " . $command['url'] . PHP_EOL; } } } ... Lingo::awesomeApi()->command('list')->send(); // GET /peoples // POST /peoples // GET peoples/{:?} // PUT peoples/{:?} // DELETE peoples/{:?}
处理身份验证
在现实世界应用中,REST服务实现了一些类型的身份验证方案。如果您正在处理一个简单的方案,如请求头中的签名或密钥,您应该简单地使用 withHeaders
命令将您的身份验证配置附加到Lingo。但某些服务使用特定的方案。要处理它,您应该在您的lingo类中定义一个 auth
配置。当前,此包支持 apiKeys
和 oauth2
身份验证方法。
apiKeys
该方法将密钥配置作为查询参数附加。
protected $sync = [ 'base_url' => 'https://protected.rest/v1', 'auth' => [ 'apiKeys' => [ 'my-key' => 'my-secret' ] ], 'commands' => [ ... ] ];
GET https://protected.rest/v1/someurl?my-key=my-secret
oauth2
该方法将处理oauth2流程以检索jwt并将其缓存到您的应用程序缓存配置。
protected $sync = [ 'base_url' => 'https://protected.rest', 'auth' => [ 'oauth2' => [ 'url' => '/oauth/token', 'grant_type' => 'client_credentials', 'client_id' => 'my-client-id', 'client_secret' => 'my-client-secret' ] ], 'commands' => [ ... ] ];
模拟模式
在测试您的应用程序时,您必须在您的 .env
中定义 APP_ENV=testing
以激活Lingo模拟模式。在此模式下,该包将绕过任何真实请求,使用模拟的静态数据。您应该在命令配置部分使用 shouldReturn
键定义这些数据。
protected $sync = [ 'base_url' => 'https://service.rest/v1', 'commands' => [ 'getMovie' => [ 'verb' => 'get', 'url' => "/movies/{:?}", 'shouldReturn' => [ 'id' => 1 'name' => 'static name', 'genre' => 'drama', 'length' => 97 ] ], ] ]; ... $movie = Lingo::awesomeApi()->command('getMovie',1)->send(); echo $movie->name; // static name
您还可以在运行时设置模拟模式如下所示
$movie = Lingo::awesomeApi()->command('getMovie',1)->withMockup(true)->send(); echo $movie->name; // static name
Lingo默认使用static
作为mockup数据模式。但您可以使用mockup
关键字设置为function
模式。这样,Lingo将依赖于一个函数来生成mockup数据。
protected $sync = [ 'base_url' => 'https://service.rest/v1', 'commands' => [ 'getMovie' => [ 'verb' => 'get', 'url' => "/movies/{:?}", 'mockup' => 'function', 'shouldReturn' => 'makeMovie' ], ] ]; ... protected function makeMovie($bindings) { $faker = \Faker\Factory::create(); return (object)[ 'id' => $bindings[0], 'name' => $faker->name, 'length' => $faker->numberBetween(90,180) ]; } ... $movie = Lingo::awesomeApi()->command('getMovie',1)->send(); echo $movie->name; // name generated by faker
异步通信
如果您的应用程序使用AWS基础设施,您可以在Lingo类中配置异步消息。为此,您必须配置您的async
部分。
protected $async = [ 'queue' => 'myqueue', 'commands' => [ 'sendEmail' => [ 'action' => 'SendEmail' ] ] ];
要发送异步消息,必须使用async
方法。
Lingo::awesomeApi()->command('sendEmail') ->withData($data) ->async() ->send();
这将把有效载荷推送到您的sqs队列
[ 'action' => 'sendEmail', 'data' => $data ]
路线图
- 单元和功能测试
- 将
sync
部分导出到swagger文件 - 在
shouldReturn
部分接受一个闭包,这样您就可以处理动态生成的mockup数据 - 在
make:lingo
中添加一个多态选项。这将很棒,例如创建一个作为接口的PaymentLingo
,以及一个作为实现PaymentLingo
的具体类StripeLingo
- 允许同步命令触发一个闭包或类方法,而不是HTTP请求。
- 自定义异常
- 内置日志系统
贡献
欢迎提交拉取请求。对于重大更改,请首先提交一个问题以讨论您想要更改的内容。
请确保根据需要更新测试。