nacosvel/feign

实现 PHP 的 Feign HTTP 客户端。

dev-main / 1.x-dev 2024-09-22 12:40 UTC

This package is auto-updated.

Last update: 2024-09-22 12:50:57 UTC


README

这是受微服务架构中使用的 Feign 客户端启发的 PHP 实现。它提供了一个轻量级的 HTTP 客户端,该客户端将声明式 Web 服务调用与易于注解的 API 集成。

GitHub Tag Total Downloads Packagist Version Packagist PHP Version Support Packagist License

特性

  • 声明式 HTTP 客户端接口
  • 注解驱动的请求处理
  • 请求和响应的自定义中间件
  • 通过各种映射和中间件接口扩展
  • 支持带有 FeignClient 注解的微服务

开发计划

  • 支持 #[EnableFeignClients] 注解
  • 支持 #[Autowired] 注解
  • 支持 #[FeignClient] 注解
  • 支持 #[RequestMapping] 注解
  • 支持 #[RequestAttribute] 注解
  • 支持 #[Middleware] 注解
  • 支持自定义响应类型
  • 实现服务发现
  • 支持无需接口依赖

安装

您可以通过 Composer 安装此软件包

composer require nacosvel/feign

快速开始

使用您的第一个项目开始非常简单。

您的项目必须支持 PSR-11

步骤 1:在您项目容器的服务提供者中构建一个 FeignRegistrar 实例。

use Nacosvel\Feign\FeignRegistrar;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        FeignRegistrar::builder();
    }

}

步骤 2:使用 #[Autowired] 注入属性。

use Nacosvel\Feign\Annotation\Autowired;
use Nacosvel\Feign\Contracts\AutowiredInterface;

class PostController implements AutowiredInterface
{
    #[Autowired]
    protected PostInterface|AutowiredInterface $post;

    public function index(): string
    {
        return $this->post->detail(name: 'nacosvel/feign', version: 'v1.0.0')->getRawContents();
    }

}

步骤 3:使用 #[FeignClient]#[RequestMapping] 定义接口。

use Nacosvel\Feign\Annotation\FeignClient;
use Nacosvel\Feign\Annotation\RequestGetMapping;
use Nacosvel\Feign\Contracts\ServiceInterface;
use Nacosvel\Feign\Contracts\TransformationInterface;

#[FeignClient(name: 'debug', path: '/')]
interface PostInterface
{
    #[RequestGetMapping(path: '/get')]
    public function detail(string $name = '', string $version = ''): Post|ServiceInterface|TransformationInterface;

}

高级用法

步骤 1:构建一个 FeignRegistrar 实例,并设置一个自定义的 Configuration 类。

use Nacosvel\Feign\Annotation\EnableFeignClients;
use Nacosvel\Feign\FeignConfiguration;
use Nacosvel\Feign\FeignRegistrar;

#[EnableFeignClients(FeignConfiguration::class)]
class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        FeignRegistrar::builder($this->app);
    }

}

步骤 2:注入属性并添加 Middleware

use Nacosvel\Feign\Annotation\Autowired;
use Nacosvel\Feign\Annotation\Middleware;
use Nacosvel\Feign\Annotation\RequestMiddleware;
use Nacosvel\Feign\Annotation\ResponseMiddleware;
use Nacosvel\Feign\Contracts\AutowiredInterface;

class PostController implements AutowiredInterface
{
    #[Autowired]
    #[Middleware(Request::class, Response::class)]
    #[RequestMiddleware(Request::class)]
    #[ResponseMiddleware(Response::class)]
    protected PostInterface|AutowiredInterface $post;

    public function index(): string
    {
        return $this->post->detail(name: 'nacosvel/feign', version: 'v1.0.0')->getRawContents();
    }

}

步骤 3:为定义接口进行更多配置。

use Nacosvel\Feign\Annotation\FeignClient;
use Nacosvel\Feign\Annotation\RequestAttribute;
use Nacosvel\Feign\Annotation\RequestGetMapping;
use Nacosvel\Feign\Annotation\Middleware;
use Nacosvel\Feign\Annotation\RequestMiddleware;
use Nacosvel\Feign\Annotation\ResponseMiddleware;
use Nacosvel\Feign\Configuration\Client;
use Nacosvel\Feign\Configuration\Configuration;
use Nacosvel\Feign\Configuration\Fallback;
use Nacosvel\Feign\Support\Service;

#[FeignClient(
    name: 'debug',
    url: 'https://httpbin.org/',
    path: '/',
    configuration: Configuration::class,
    fallback: Fallback::class,
    client: Client::class
)]
#[Middleware(Request::class, Response::class)]
#[RequestMiddleware(Request::class)]
#[ResponseMiddleware(Response::class)]
interface PostInterface
{
    #[RequestGetMapping(path: '/get?id={id}', params: 'id=123456')]
    #[RequestAttribute(value: RequestAttribute::QUERY)]
    #[Middleware(Request::class, Response::class)]
    #[RequestMiddleware(Request::class)]
    #[ResponseMiddleware(Response::class)]
    public function detail(string $name = '', string $version = ''): Post|Service;

}

高级示例

此实现增强了 Feign,使其能够在不依赖定义的接口的情况下支持远程微服务调用。此功能允许更灵活的远程服务调用,您不需要为每个服务预先定义接口。

use Nacosvel\Feign\Annotation\Autowired;
use Nacosvel\Feign\Annotation\RequestGetMapping;
use Nacosvel\Feign\Contracts\AutowiredInterface;
use Nacosvel\Feign\Contracts\ReflectiveInterface;

class PostController implements AutowiredInterface
{
    #[Autowired]
    #[FeignClient(name: 'debug', url: 'https://httpbin.org/', path: '/')]
    #[RequestGetMapping(path: '/uuid')]
    protected ReflectiveInterface $post;

    public function index(): string
    {
        return $this->post->uuid()->getRawContents();
    }

}

文档

配置参考

public function getDefaultMethod(): string;

获取默认请求方法,在未指定时生效。

public function converters(): array;

重写此方法可以实现自定义响应类型。

public function getService(?string $name = null): string|array|null;

从多个服务地址中随机选择一个服务。

回退参考

public function __invoke(
        RequestInterface  $request,
        ResponseInterface $response,
        array             $options = [],
        Throwable         $previous = null
    ): ResponseInterface;

在此处可以统一处理异常响应。

客户端参考

public function __invoke(): ClientInterface;

对于自定义请求实例,您需要返回 GuzzleHttp\ClientInterface 的一个实例。

许可

Nacosvel Feign 在MIT许可证(MIT)下提供。请参阅许可证文件以获取更多信息。