分享一个简单的 laravel SDK 抽象基础类

分享一个简单的 laravel SDK 抽象基础类(FoundationSdk.php)。

使用示例

<?php
/* @var \App\Services\Sdk\FooSdk $fooSdk */
$fooSdk = app('foo');
$ret = $fooSdk
    ->dump()
    ->withLogMiddleware()
    ->tapPendingRequest(function ($pendingRequest){
        // tap pendingRequest.
    })
    ->bar([
        'foo' => 1,
        'bar' => 'bar',
    ]);

编写 sdk

1、继承 FoundationSdk.php 抽象类,实现 validateConfiginitPendingRequest 方法。

<?php

namespace App\Services\Sdk;

use GuzzleLogMiddleware\Handler\MultiRecordArrayHandler;
use GuzzleLogMiddleware\LogMiddleware;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Symfony\Component\OptionsResolver\OptionsResolver;

class FooSdk extends FoundationSdk
{
    /**
     * 示例方法
     *
     * @param $data
     *
     * @return \GuzzleHttp\Promise\PromiseInterface|\Illuminate\Http\Client\Response
     */
    public function bar($data)
    {
        return $this->pendingRequest->post('uri/xxx', configure_options($data, function (OptionsResolver $optionsResolver) {
            $optionsResolver
                ->setDefined([
                    'foo',
                    'bar',
                ])
                ->setRequired([
                    'foo',
                    'bar',
                ])
                ->addAllowedValues('foo', [0, 1])
                ->addAllowedTypes('bar', 'string')
                ->setDefaults([
                    'foo' => 0
                ]);
        }));
    }

    /**
     * 验证配置
     * 个人喜欢用 `symfony/options-resolver` 验证参数
     * 当然也可以用 laravel 自带的验证规则去验证
     */
    protected function validateConfig(array $config): array
    {
        return configure_options($config, function (OptionsResolver $optionsResolver) {
            $optionsResolver
                ->setDefined([
                    'baseUrl',
                    'token',
                    'options'
                ])
                ->setRequired([
                    'baseUrl',
                    'token',
                    'options'
                ])
                ->addAllowedTypes('baseUrl', 'string')
                ->addAllowedTypes('token', 'string')
                ->addAllowedTypes('options', 'array');
        });
    }

    /**
     * 初始化 PendingRequest
     */
    protected function initPendingRequest(array $config): PendingRequest
    {
        return Http::withOptions($this->config['options'])
            ->baseUrl($this->config['baseUrl'])
            ->asJson()
            ->withMiddleware(new LogMiddleware(Log::channel('daily'), new MultiRecordArrayHandler(null, 1048576, 1048576)));
    }
}
<?php

use Symfony\Component\OptionsResolver\OptionsResolver;

if (! function_exists('configure_options')) {
    /**
     * Configuration options.
     *
     * @param \Closure $closure
     *
     * @return array
     */
    function configure_options(array $options, Closure $closure)
    {
        $resolver = new OptionsResolver();

        $closure($resolver);

        return $resolver->resolve($options);
    }
}

2、添加配置 config/services.php

<?php

return [
    ...
    'foo' => [
        'baseUrl' => env('FOO_BASE_URL', 'http://xxxxx'),
        'token' => env('FOO_TOKEN', ''),
        'options' => []
    ],
    ...
];

3、注册绑定服务

<?php

namespace App\Providers;

use App\Services\Sdk\FooSdk;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;

class ExtendServiceProvider extends ServiceProvider implements DeferrableProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(FooSdk::class, function (Application $app) {
            return new FooSdk(config('services.foo'));
        });
        $this->app->alias(FooSdk::class, 'foo');
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return [
            FooSdk::class, 'foo',
        ];
    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
No practice, no gain in one's wit. 我的 Gitub
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
45
粉丝
110
喜欢
903
收藏
1264
排名:45
访问:14.6 万
私信
所有博文
社区赞助商