paknahad / jsonapi-bundle
jsonapi-bundle是一个Symfony包。使用woohoolabs/yin生成基于JsonApi.org的API最快的方法。
Requires
- php: >=7.1.3
- ext-json: *
- doctrine/inflector: ^2.0
- nyholm/psr7: ^1.4
- sensio/framework-extra-bundle: ^5.5|^6.0
- symfony/orm-pack: ^1.0|^2.0
- symfony/proxy-manager-bridge: ^4.4|^5.0|^6.0
- symfony/psr-http-message-bridge: ^2.0
- symfony/validator: ^4.4|^5.0|^6.0
- woohoolabs/yin: ^4.3
Requires (Dev)
- friendsofphp/php-cs-fixer: *
- opis/json-schema: ^2.2
- phootwork/collection: ^2.0|^3.0
- phpstan/phpstan: ^1.2
- phpstan/phpstan-phpunit: ^1.0
- roave/security-advisories: dev-latest
- symfony/maker-bundle: ^1.36
- symfony/phpunit-bridge: ^4.4|^5.0|^6.0
- symfony/process: ^5.0
- symfony/security-core: ^4.4|^5.0|^6.0
- symfony/translation: ^4.4|^5.0|^6.0
- symfony/yaml: ^4.4|^5.0|^6.0
This package is auto-updated.
Last update: 2024-09-13 15:18:11 UTC
README
JsonApiBundle For Symfony
JsonApiBundle是一个Symfony包。使用JsonApi和woohoolabs/yin库生成API最快的方法。
安装
-
安装symfony
composer create-project symfony/skeleton YOUR_PROJECT
-
composer require symfony/maker-bundle phootwork/collection --dev
-
安装此包
composer require paknahad/jsonapi-bundle
对于Symfony 4使用
composer require paknahad/jsonapi-bundle:^3.1
-
将以下行添加到
config/bundles.php
Paknahad\JsonApiBundle\JsonApiBundle::class => ['all' => true],
用法
-
使用以下命令逐个生成实体
bin/console make:entity
例如,Book和Author实体如下所示
use Doctrine\ORM\Mapping as ORM; class Book { /** * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer") */ private $id; /** * @ORM\Column(type="string", length=255) */ private $title; /** * @ORM\Column(type="string", length=20, nullable=true) */ private $isbn; /** * @ORM\ManyToMany(targetEntity="App\Entity\Author", inversedBy="books") */ private $authors; ...
use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; class Author { /** * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer") */ private $id; /** * @ORM\Column(type="string", length=255) * @Assert\NotBlank() * @Assert\Length(min=3) */ private $name; /** * @ORM\ManyToMany(targetEntity="App\Entity\Book", mappedBy="authors") */ private $books; ...
-
生成CRUD API
bin/console make:api
-
您可以在以下路径找到生成的"collections",并在其中测试API
collection/postman.json collection/swagger.yaml
特性
分页
http://example.com/books?page[number]=5&page[size]=30
排序
- 按名称字段升序:
http://example.com/books?sort=name
- 按名称字段降序:
http://example.com/books?sort=-name
- 多个字段:
http://example.com/books?sort=city,-name
- 关系字段:
http://example.com/books?sort=author.name
关系
http://example.com/books?include=authors
多个关系
http://example.com/books?include=authors.phones,publishers
搜索
由于JSON API规范没有确切指定过滤应该如何工作,可以使用不同的过滤方法。每种方法都提供了Finder服务。每个注册的Finder都将能够向搜索查询添加条件。如果您注册了多个Finder,它们将同时激活。这使您的API能够支持多种过滤方法。
基本Finder。
该库包含一个基本的Finder,提供简单的过滤功能。
此请求将返回所有作者姓名以"hamid"开头的书籍。
http://example.com/books?filter[authors.name]=hamid%
以下行有附加条件:标题中包含"php"的书籍。
http://example.com/books?filter[title]=%php%&filter[authors.name]=hamid%
在IndexAction上设置默认过滤器
使用$resourceCollection->getQuery()
可以访问查询对象。使用"r"别名引用当前实体。在这个例子中,"r"指的是"ProjectEntity"。
use Symfony\Component\Routing\Annotation\Route; class ProjectController extends Controller { /** * @Route("/", name="projects_index", methods="GET") */ public function index(ProjectRepository $projectRepository, ResourceCollection $resourceCollection): ResponseInterface { $resourceCollection->setRepository($projectRepository); $resourceCollection->getQuery()->where('r.user_id = :s1')->setParameter(...); $resourceCollection->handleIndexRequest(); return $this->jsonApi()->respond()->ok( new ProjectsDocument(new ProjectResourceTransformer()), $resourceCollection ); }
其他Finder
目前,以下Finder可以通过其他包获得
-
mnugter/jsonapi-rql-finder-bundle - 基于RQL的Finder
-
paknahad-jsonapi-querifier-bundle - 基于Querifier的Finder
创建自定义Finder
Finder可以通过服务定义中的服务标签进行注册。必须将标签paknahad.json_api.finder
添加到服务中,以便注册Finder。
示例
<service class="Paknahad\JsonApiBundle\Helper\Filter\Finder" id="paknahad_json_api.helper_filter.finder"> <tag name="paknahad.json_api.finder" /> </service>
每个Finder都必须实现Paknahad\JsonApiBundle\Helper\Filter\FinderInterface
接口。请参阅\Paknahad\JsonApiBundle\Helper\Filter\Finder
以获取实现示例。
如果您需要更多对查找器的控制,您可以使用 \Paknahad\JsonApiBundle\Helper\Filter\FinderSupportsInterface
接口,并在 supports()
方法内部实现条件逻辑。
use Paknahad\JsonApiBundle\Helper\Filter\FinderSupportsInterface; use Paknahad\JsonApiBundle\Helper\FieldManager; use Symfony\Component\HttpFoundation\Request; class CustomFinder implements FinderSupportsInterface { public function supports(Request $request, FieldManager $fieldManager): bool { // based on some request data if ($request->query->has('some-flag')) { return true; } // based on document field manager if ($fieldManager->getRootEntity() === Author::class) { return true; } return false; } }
验证
验证关联时出错
{ "jsonapi": { "version": "1.0" }, "errors": [ { "detail": "Invalid value for this relation", "source": { "pointer": "/data/relationships/authors", "parameter": "1" } } ] }
如果您在实体上定义了验证器,请验证属性。
{ "jsonapi": { "version": "1.0" }, "errors": [ { "detail": "This value is too short. It should have 3 characters or more.", "source": { "pointer": "/data/attributes/name", "parameter": "h" } } ] }
错误处理器
所有错误,如
- 内部服务器错误(500)
- 未找到(404)
- 拒绝访问(403)
有如下响应
{ "meta": { "code": 0, "message": "No route found for \"GET /book\"", "file": "/var/www/vendor/symfony/http-kernel/EventListener/RouterListener.php", "line": 139, "trace": [ { "file": "/var/www/vendor/symfony/event-dispatcher/EventDispatcher.php", "line": 212, "function": "onKernelRequest" }, { "file": "/var/www/vendor/symfony/event-dispatcher/EventDispatcher.php", "line": 44, "function": "doDispatch" }, { "file": "/var/www/vendor/symfony/http-kernel/HttpKernel.php", "line": 125, "function": "dispatch" }, { "file": "/var/www/vendor/symfony/http-kernel/HttpKernel.php", "line": 66, "function": "handleRaw" }, { "file": "/var/www/vendor/symfony/http-kernel/Kernel.php", "line": 188, "function": "handle" }, { "file": "/var/www/public/index.php", "line": 37, "function": "handle" } ] }, "links": { "self": "/book" }, "errors": [ { "status": "404", "code": "NO_ROUTE_FOUND_FOR_\"GET_/BOOK\"", "title": "No route found for \"GET /book\"" } ] }
注意:仅在开发环境中填充“meta”字段。
配置
您可以使用以下选项配置此包
#config/packages/json_api.yaml json_api: documentationSchema: 'openapi' controllerNamespace: 'Controller'
支持的文档模式是 openapi
和 swagger
。如果您想在不同命名空间中生成控制器,例如 Controller\Api
,可以使用控制器命名空间配置选项。要前缀 Api 路由,可以使用 Symfony 路由配置。
#config/routes/annotations.yaml api: resource: ../../src/Controller/Api type: annotation prefix: /api