此软件包最新版本(1.0.0-beta6)的许可信息不可用。

一个使用 Amp 和 Annotated Container 构建异步应用的框架。

1.0.0-beta6 2019-11-03 15:06 UTC

README

Travis GitHub license GitHub release

Labrador HTTP 是一个创建功能丰富、遵循 SOLID 原则的 Web 应用的框架。它主要是一组关于整合以下库的意见:

这并不是所有依赖项的详尽列表,只是涉及主要整合点的那些。

请查看下面的快速入门以了解更多关于 Labrador HTTP 新特性的细节。

安装

使用 Composer 安装库。

composer require cspray/labrador-http:dev-main

快速入门

Labrador 最独特的特点是其与 Annotated Container 的集成,允许以下功能:

  • 将请求的特定部分注入到控制器方法中
  • 基于 JSON 编码的请求体注入自定义 DTO 对象
  • 使用 FastRoute 和属性指定路由映射。

最好的方式是展示一个实现此功能的控制器。

<?php declare(strict_types=1);

namespace LabradorDemo;

use Amp\Http\Server\Response;use Labrador\Web\Controller\Dto\Dto;use Labrador\Web\Controller\Dto\RouteParam;use Labrador\Web\Controller\RouteMapping\ControllerActions;use Labrador\Web\Controller\RouteMapping\Get;use Labrador\Web\Controller\RouteMapping\Post;use League\Uri\Components\Query;use Psr\Log\LoggerInterface;use Ramsey\Uuid\UuidInterface;

#[ControllerActions]
final class WidgetController {

    // The $logger will be a Monolog logger that sends output to stdout using amphp/log
    public function __construct(
        private readonly LoggerInterface $logger
    ) {}

    // The $filter will be injected from the query parameters sent in the request
    // The $widgetGatherer is an injected service and will be the same instance, unlike $filter
    #[Get('/widgets')]
    public function list(Query $filter, WidgetGatherer $widgetGatherer) : Response {
        // do some stuff to generate a response 
    }
    
    // The $widgetId will be injected from the value sent in the route
    // The $widgetGatherer is an injected service and will be the same instance, unlike $widgetId
    #[Get('/widgets/{id}')]
    public function fetch(#[RouteParam('id')] UuidInterface $widgetId, WidgetGatherer $widgetGatherer) : Response {
        // do some stuff to generate a response 
    }
    
    // The $widget will be created using cuyz/valinor from the JSON decoded Request body
    // The $creator is an injected service and will be the same instance, unlike $widget
    #[Post('/widgets')]
    public function create(#[Dto] Widget $widget, WidgetCreator $creator) : Response {
        // do some stuff to generate a response 
    }

}

请求注入

Labrador HTTP 还提供了一套属性或特定类型映射,用于获取请求的特定部分。

<?php declare(strict_types=1);

namespace LabradorDemo;

use Amp\Http\Server\RequestBody;use Amp\Http\Server\Response;use Labrador\Controller\Dto\QueryParams;use Labrador\Controller\Dto\Url;use Labrador\Web\Controller\Dto\Body;use Labrador\Web\Controller\Dto\Header;use Labrador\Web\Controller\Dto\Headers;use Labrador\Web\Controller\Dto\Method;use Labrador\Web\Controller\Dto\RouteParam;use Labrador\Web\Controller\RouteMapping\ControllerActions;use Labrador\Web\Controller\RouteMapping\Get;use Labrador\Web\Controller\RouteMapping\Post;use League\Uri\Components\Query;use League\Uri\Contracts\QueryInterface;use Psr\Http\Message\UriInterface;

#[ControllerActions]
class RequestInjectionController {

    #[Get('/headers')]
    public function headers(#[Headers] array $headers) : Response {
        // ...  
    }

    #[Get('/header-array')]
    public function headerAsArray(#[Header('Accept')] array $accept) : Response {
        // ... 
    }
    
    #[Get('/header-string')]
    public function headerAsString(#[Header('Authorization')] string $token) : Response {
        // ... 
    }
    
    #[Get('/url/attr')]
    public function url(#[Url] UriInterface $uri) : Response {
        // ...
    }
    
    #[Get('/method')]
    public function method(#[Method] string $method) : Response {
        // ...
    }
    
    #[Get('/body/buffered')]
    public function body(#[Body] string $body) : Response {
        // ... 
    }
    
    #[Post(('/body/stream'))]
    public function bodyStream(#[Body] RequestBody $body) : Response {
        // ...
    }
    
    #[Get('/query/string')]
    public function queryAsString(#[QueryParams] string $query) : Response {
        // ...
    }
    
    #[Get('/query/interface')]
    public function queryAsInterface(#[QueryParams] QueryInterface $query) : Response {
        // ...
    }
    
    #[Get('/query/object')]
    public function queryAsObject(#[QueryParams] Query $query) : Response {
        // ...
    }
    
    #[Get('/route/{foo}/param/{bar}')]
    public function routeParam(
        #[RouteParam('foo')] string $fooParam,
        #[RouteParam('bar')] string $barParam
    ) : Response {
        // ... 
    }
    
    // Some parameters you can simply provide a type and not have to attribute it
    
    #[Get('/uri/implied')]
    public function uriImplied(UriInterface $uri) : Response {
        // ...
    }
    
    #[Get('/query/implied')]
    public function queryImplied(Query $query) : Response {
        // ...
    }
    
    #[Get('/body/implied')]
    public function bodyImplied(RequestBody $body) : Response {
        // ...
    }
    
}