recras / sf-doctrine-rest-generator-plugin
sfDoctrineRestGeneratorPlugin 的分支
Requires
Requires (Dev)
- phpstan/phpstan: 1.7.15
- recras/doctrine1: *
- dev-master
- 1.2.10
- 1.2.9
- 1.2.8
- 1.2.7
- 1.2.6
- 1.2.5
- 1.2.4
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.1
- 1.1.0
- 1.0.0
- dev-undo-public-output
- dev-output-public
- dev-php82compat
- dev-model-typehint
- dev-php8-preparation
- dev-typehints-validators
- dev-remove-default-generated-test
- dev-remove-serializers
- dev-phpstan
- dev-refactoring-add-typehint
- dev-allow-specified-function-object-additional-fields
- dev-accept-postvalidator-sfvalidatorbase
- dev-remove-embed-manytomany
- dev-loadRelated
- dev-embedManyToManyRelationsInShow
- dev-update-resolve-object-first
- dev-validator
- dev-refactor-query-for-inheritance
- dev-putPostContent
This package is auto-updated.
Last update: 2022-12-15 12:30:24 UTC
README
介绍
此插件允许根据 Doctrine 模型生成 REST 模块。它允许轻松创建 REST Web 服务,并提供一个可扩展的数据交换框架。以下是关键特性:
- REST 模块生成 "类似 admin-generator"
- 易于定制的 generator.yml 配置文件
- 使用 symfony 验证器验证传递给服务的参数
- JSON 序列化
- 在检索以及创建请求中嵌入相关模型的可能性
- 嵌入额外字段的可能
- 限制结果数量的能力,带或不带分页
- 支持约束联合(例如,http://api.example.org/city?city_id=12,13,14)
- 通过事件和过滤器可钩入
- 抽象和可替换对象的序列化
- 全面支持 HTTP(GET、POST、PUT、DELETE)
- 为每个生成的模块进行功能测试
如何安装
-
前往您项目的根目录
-
安装插件
./symfony plugin:install --stability=beta sfDoctrineRestGeneratorPlugin
-
清除缓存
./symfony cc
-
或者,您可能更喜欢将此插件作为 Subversion 依赖项安装。在这种情况下,以下是存储库: http://svn.symfony-project.com/plugins/sfDoctrineRestGeneratorPlugin。GitHub 上还有一个 Git 镜像:https://github.com/xavierlacot/sfDoctrineRestGeneratorPlugin
用法
REST 模块生成
生成 REST 模块相当简单
./symfony doctrine:generate-rest-module APPLICATION MODULE MODEL
这将创建一个名为 "MODULE" 的模块,位于 "APPLICATION" 应用程序中,该模块将配置为通过 REST 风格的服务公开 "MODEL" 模型。
生成的文件
假设我们有一个以下模型
Post:
actAs: [ Timestampable ]
columns:
post_category_id: integer(4)
created_by: integer
title: {type: string(128), notnull: true}
summary: {type: string(255), notnull: true}
body: clob
relations:
CreatedBy: { class: sfGuardUser, onDelete: SET NULL, local: created_by, foreign: id, foreignAlias: CreatedPost }
PostCategory: { class: PostCategory, onDelete: SET NULL, local: post_category_id, foreign: id }
PostCategory:
columns:
id: { type: integer(4), primary: true, autoincrement: true }
name: { type: string, size: 100, notnull: true, unique: true }
description: clob
is_enabled: { type: boolean, default: true }
如果我们想通过 REST API 公开 "Post" 模型,我们只需输入以下命令
./symfony doctrine:generate-rest-module api post Post
这将生成以下内容
-
在 "api" 应用的
routing.yml
文件中创建一个新的路由post: class: sfObjectRouteCollection options: model: Post actions: [ create, delete, list, show, update ] module: post column: id format: xml
-
一个名为 "post" 的 RESTgen 模块,位于 apps/api/modules/post,包含四个子目录
- actions:包含一个 "postActions" 类,该类扩展了一个动态生成的 "autopostActions" 类
- config:包含生成模块的 generator.yml 和 view.yml 文件(有关如何配置生成模块的说明,请参阅 "服务配置" 章节),
- lib:包含一个空的 "postGeneratorConfiguration" 类,该类扩展了一个动态生成的 "BasePostGeneratorConfiguration" 类
- templates
-
在第一次请求 REST 模块后,缓存目录将包含生成模块的代码,特别是 "autopostActions" 类的代码,您应该检查以了解插件的工作方式。
您可以在 http://api.example.com/post.json 上看到您的帖子作为 JSON 提要
如果情况不是这样,请检查 routing.yml 文件,确认路由名称前是否带有减号 "p"。如果您想更改 API 的公开 URI,只需更改路由名称,然后清除您项目的缓存。以下配置将 API 公开在 http://api.example.com/myPostAPI.json
myPostAPI:
class: sfObjectRouteCollection
options:
model: Post
actions: [ create, delete, list, update ]
module: post
column: id
format: xml
主配置
在配置 webservice 的响应内容之前,最重要的配置步骤必须经过。它们解决了一些影响安全、稳定性的通用问题,并定义了 webservice 应该做什么
- webservice 支持哪些类型的操作?仅仅是获取对象,还是也可以创建/更新/删除它?
- 如何访问 webservice?主要的安全指南是什么?
允许的操作
REST web 服务支持五种不同的操作
- 获取项目列表("list"):http://api.example.com/post.json(
GET
方法), - 获取单个项目("show"):http://api.example.com/post/1.json(
GET
方法) - 创建新项目("create"):http://api.example.com/post.json(
POST
方法), - 更新现有项目("update"):http://api.example.com/post/123.json(
PUT
方法,值 "123" 必须替换为要更新的对象的主键), - 删除现有项目("delete"):http://api.example.com/post/123.json(
DELETE
方法,值 "123" 必须替换为要删除的对象的主键),
这些操作中的每一个都可以在路由文件中允许或禁止,使用 actions
键:只启用您要使用的操作。
安全指南
您永远不应该忘记,公开具有写访问权限的 webservice 可能会危害您的数据。由于对您的 webservice 安全性的关注不够,您可能会丢失一些重要数据,或者在不应该的情况下更改数据。
首先,确保只允许严格必要的操作。如果客户端不需要使用 webservice 删除项目,请在 routing.yml
文件中禁用此操作。
其次,考虑一种方法来提高您的 webservice 的安全性
- 尽可能使用 SSL,以确保上传的数据不会被第三方(中间人)截获和更改,
- 使用 HTTP 身份验证,
- 使用更强大/更灵活的认证系统(例如 OAuth),
- 向您的客户端提供唯一的 API 密钥,并检查他们对 API 的使用情况。
详细服务配置
对于 symfony 的 admin-generator,REST 生成器会根据在 generator.yml
文件中完成的配置动态生成代码。
以下是 generator.yml
文件的默认内容
generator:
class: sfDoctrineRestGenerator
param:
model_class: Post
config:
default:
# fields: # list here the fields.
# created_at: { date_format: 'Y-m-d\TH:i:s', tag_name: 'created' } # for instance
# separator: ',' # separator used for multiple filters
get:
# additional_params: [] # list here additional params names, which are not object properties
# display: [] # list here the fields to render in the response
# embed_relations: [] # list here relations to embed in the response
# embedded_relations_hide:
# Category: [id] # you can hide fields inside a certain embedded relation
# global_additional_fields: [] # list here additionnal calculated global fields
# hide: [id] # list here the fields you don't want to expose
# max_items: 0 # uncomment to fix an absolute limit to the number of items in the response
# object_additional_fields: [] # list here additional calculated fields
# pagination_enabled: false # set to true to activate the pagination
# pagination_custom_page_size: false # set to true to allow the client to pass a page_size parameter
# pagination_page_size: 100 # the default number of items in a page
# sort_custom: false # set to true to allow the client to pass a sort_by and a sort_order parameter
# sort_default: [] # set to [column, asc|desc] in order to sort on a column
# filters: # list here the filters
# id:
# compare: { less: , greaterEqual: moreThan } # generate filters idLess and idMoreThan
# created_at: { date_format: 'd-m-Y', multiple: true } # for instance
create:
# disable_validators: [ created_at ] # list here validators that should not be generated
在上一个示例中注释的不同可能参数将在以下章节中详细说明。
model_class
model_class
参数定义了 REST 模块所绑定的 Doctrine 模型的名称。
默认值
default
选项包含多个通用配置指令
字段
“fields”选项包含每个模型字段的装饰选项数组,这些选项在序列化和反序列化过程中使用。它可能包括:
date_format
:用于格式化字段的日期格式。这必须是可以由date()函数接受的格式。tag_name
:用于显示此字段的标签名称。例如,您可能希望将文章的标题关联到“post_title”键而不是“title”。type
:用于显示此字段的类型。支持所有PHP类型转换关键字,null值保留。
separator
在通过URL传递对象的键时使用的分隔符。生成的模块允许通过它们的ID要求多个资源:http://api.example.com/post/?id=12,17,19
get
get
选项列出了针对“get”操作特定的几个选项。
additional_params
additional_params
选项允许定义一个参数名称数组,Web服务将接受这些参数。
生成器中参数的验证相当严格,对于传递给服务的每个未识别的参数,生成器都会抛出异常。此选项允许对于某些参数类型不抛出此异常,即使这些参数实际上没有被生成器使用。
此参数的目的是允许将第三方参数传递到服务中。例如,您可能希望传递一个“token”或“api_key”参数,然后可以使用它来检查客户端是否有权使用该服务。
display
display
选项包含要输出到XML或JSON源的字段列表。例如,对于之前定义的“Post”模型,您可以通过更改此参数仅显示标题和作者的ID。
config:
get:
display: [ title, author_id ]
如果此选项留空,则将渲染模型的全部字段。
您可能还感兴趣的是hide
选项,它允许隐藏模型的一些字段。
embed_relations
embed_relations
选项包含要嵌入的Doctrine关系列表。它可以是1-n或n-n关系,其内容将嵌入到每个对象中。以下是针对“Post”模型的有效配置:
config:
get:
embed_relations: [ PostCategory ]
此配置将产生如下源:
...
<Post>
<Id>1</Id>
<PostCategoryId>2</PostCategoryId>
<CreatedBy>26</CreatedBy>
<Title>Here the title of my post</Title>
<Summary>Here the summary of my post</Summary>
<Body>Here the body of my post</Body>
<PostCategory>
<Id>2</Id>
<Name>Name of the category</Name>
<Description>Description of the category</Description>
<IsEnabled>1</IsEnabled>
</PostCategory>
</Post>
...
需要考虑的几个事项
- 您不能定义在相关对象中要渲染的字段,但可以使用
embedded_relations_hide
选项隐藏某些字段。 - 响应包含
PostCategoryId
字段和PostCategory.Id
字段。您可以通过使用display
或hide
选项来节省一些字节,以删除PostCategoryId
字段。
embed_relations_custom
embed_relations_custom
选项包含可能嵌入的Doctrine关系列表。只有当请求中存在embed
参数时,这些关系才会被嵌入。其行为与embed_relations
选项一致。以下是针对“Post”模型的有效配置:
config:
get:
embed_relations_custom: [ PostCategory ]
如果提供了embed
请求参数,此配置将生成如下格式的feed:
...
<Post>
<Id>1</Id>
<PostCategoryId>2</PostCategoryId>
<CreatedBy>26</CreatedBy>
<Title>Here the title of my post</Title>
<Summary>Here the summary of my post</Summary>
<Body>Here the body of my post</Body>
<PostCategory>
<Id>2</Id>
<Name>Name of the category</Name>
<Description>Description of the category</Description>
<IsEnabled>1</IsEnabled>
</PostCategory>
</Post>
...
embedded_relations_display
您可能只想显示结果中的特定字段。这些字段可以通过embedded_relations_display
配置选项进行配置
config:
get:
embedded_relations_display:
PostCategory:
- name
- description
注意:此配置选项仅在设置display
选项时有效。如果没有为某个嵌入设置embedded_relations_display
选项,则将选择所有字段。
embedded_relations_hide
您可能想隐藏嵌入关系中的某些字段。例如,您可能想从PostCategory模型中隐藏id
字段。这可以使用embedded_relations_hide
配置选项完成
config:
get:
embedded_relations_hide:
PostCategory: [id]
global_additional_fields
在某些情况下,您可能想将一些附加字段嵌入到XML或JSON响应中。例如,您可能想包括帖子总数、平均价格等。
global_additional_fields
在这种情况下很有帮助。它包含您想要添加的字段数组,并且为每个字段,生成器将创建一个用于嵌入该字段的方法。以下是一个可能的配置:
config:
get:
global_additional_fields: [ TotalPosts ]
这将创建一个空方法,必须在生成的模块中手动覆盖,以包含您选择的附加字段。
public function embedGlobalAdditionalTotalPosts($params)
{
$totalObjects = count($this->objects);
$this->objects['NbObjects'] = $totalObjects;
}
hide
hide
选项包含要在XML或JSON feed中隐藏的字段列表。例如,对于之前定义的"Post"模型,您可以选择通过更改此参数来隐藏其id
。
config:
get:
hide: [id]
此选项比"display"选项具有更高的优先级,这意味着如果同时使用这两个选项,则仅渲染未列入"hide"选项的字段。
max_items
此指令允许将绝对限制设置在响应中的项目数量上。此参数比pagination_page_size
指令具有更高的优先级,以及可能由用户定义的page_size
参数。
默认情况下没有限制。将此键设置为0将禁用限制。
object_additional_fields
object_additional_fields
包含要在响应的每个项目中嵌入的附加字段列表。例如,如果您想添加一个字段NbWords
,该字段会给出帖子正文的单词数,请使用以下配置:
config:
get:
object_additional_fields: [ NbWords ]
这将创建一个空方法,必须在生成的模块中手动覆盖,以包含您选择的附加字段。
public function embedAdditionalNbWords($item, $params)
{
$array = $this->objects[$item];
$array['NbWords'] = str_word_count($array['body']);
$this->objects[$item] = $array;
}
此选项对于仅嵌入少量字段的关系很有用(参见embed_relations
选项)
- 嵌入关系
- 使用
object_additional_fields
选项取消设置不需要的字段。
embedAdditionalXXX()
方法应始终采用以下形式(生成器会以注释的形式生成此代码):
public function embedAdditionalXXXX($item, $params)
{
$array = $this->objects[$item];
// here go some manipulation of $array
$this->objects[$item] = $array;
}
也可以指定调用以添加字段的函数
config: get: object_additional_fields: is_deleted: additionalFieldIsDeleted
指定的函数应具有以下签名
function additionalFieldIsDeleted(array $object, array $parameters): mixed { // $object contains the object as it currently is formatted // $parameters contains the request parameters from this API call // return the value you'd like field "is_deleted" to have }
指定的函数将以这种方式被调用
// in formatObjects: $this->objects[$key]['is_deleted'] = $this->additionalFieldIsDeleted($this->objects[$key], $parameters);
pagination_enabled
此选项定义是否启用分页。默认为false。如果启用,服务将允许在请求中传递"page"参数。请求可以是以下形式:http://api.example.org/post/?page=3
分页自定义页面大小
将此选项设置为true,允许客户端传递一个page_size
参数。否则,分页将具有固定的大小。如果pagination_enabled
选项设置为false,此选项将没有效果。
分页页面大小
此选项定义分页的默认页面大小。如果pagination_enabled
选项设置为false,此选项将没有效果。
自定义排序
将此选项设置为true
,允许客户端在查询字符串中传递sort_by
和sort_order
参数。否则,客户端将无法对结果进行排序。
默认排序
sort_default
选项定义默认的排序顺序。此选项的格式为[column, asc|desc]。例如
config:
get:
sort_default: [ created_at, desc ]
过滤器
此选项允许通过设置一些选项来覆盖默认的过滤行为。默认情况下,插件允许根据模型字段过滤结果。对于每个字段,可以在查询字符串中传递一个值,该值将用于选择匹配的项目。
例如,您可能只想通过请求中的category_id参数获取特定类别的帖子。如果您想允许客户端请求多个类别的帖子,您必须明确允许它,因为这可能会创建更复杂(即资源消耗大且速度慢)的请求。为此,必须将此字段名的键multiple
设置为true
。
config:
get:
filters:
category_id: { multiple: true }
这将允许一次性调用包含多个category_ids的webservice,请求形式为http://api.example.org/post/?category_id=1,4,5
对于日期字段,您可能想告诉插件接受的日期格式。例如
config:
get:
filters:
created_at: { date_format: 'd-m-Y' }
要比较某个字段与给定的值,可以向某个字段添加一个compare
指令以添加过滤器。这些过滤器具有fieldNameOperator
名称,以下操作符受支持
- less
- lessEqual
- greater
- greaterEqual
比较过滤器可选地带有别名名称,该名称覆盖了参数中的默认操作符名称。
例如,要向created_at
字段添加比较过滤器
config:
get:
filters:
created_at:
compare:
less: before # generates the created_atBefore filter
lessEqual: before # generates the created_atLessEqual filter
greater: after # generates the created_atAfter filter
# greaterEqual will not be generated
创建
create
选项列出针对"创建"操作特定的几个选项
禁用验证器
disable_validators
选项包含不应生成创建验证器的字段名称列表。例如
config:
create:
disable_validators: [ created_at, updated_at ]
其他配置变量
某些其他配置变量在默认配置文件中不存在
actions_base_class
参数允许更改由模块的动作类扩展的基本动作类名称。这允许您使用自己的动作类,该类可能包含您希望在不同REST模块中使用的多个方法。
事件
截至版本0.9.1,该插件在几个地方使用事件,以提高重载和扩展默认行为。
以下是支持的事件名称列表
sfDoctrineRestGenerator.filter_error_output
:此事件用于过滤错误消息并允许其自定义sfDoctrineRestGenerator.filter_results
:此事件用于过滤查询结果数组(添加、删除或更改其某些键)。请注意,您可以通过在generator.yml
中使用object_additional_fields
参数来实现相同的功能sfDoctrineRestGenerator.filter_result
:此事件用于过滤单个查询结果(添加、删除或更改其某些键)。请注意,您可以通过在generator.yml
中使用object_additional_fields
参数来实现相同的功能sfDoctrineRestGenerator.get.pre
:此事件在请求的开始处触发(在executeIndex()
的开始处)
愿望清单
如果您使用此插件并想帮助我改进它,可以考虑以下主题之一
- 嵌套
embed_relations
参数的可能性(而不仅仅是限制在单个级别) - 禁用事件通知/过滤(性能)的可能性
- 更多的序列化器(例如BSON或RDF)。目前,该插件仅允许将结果集序列化为XML、YAML或JSON数据流(请参阅“序列化”章节)。需要尽可能紧凑的数据流的移动客户端将受益于BSON序列化。
- 生成客户端库(sfDoctrineRestClientGenerator ?)的可能性
- 生成单元测试的可能性
- 生成API文档的可能性
- 记录身份验证解决方案
- 所有可能的反馈!
向插件贡献力量,寻求帮助
请在symfony用户邮件列表上寻求如何使用该插件的帮助。您也可以直接给我发邮件:xavier@lacot.org。
许可和致谢
此插件由Xavier Lacot开发,并受MIT许可协议的许可。
变更日志
trunk
- 默认启用
show
路由
版本0.9.4 - 2010-11-25
- 允许在同一个请求中创建或更新相关对象:以递归方式解析有效负载,递归验证有效负载数组,递归生成验证器数组。感谢dfeyer在此方面的贡献
- 添加了基本“显示”操作(感谢dfeyer)
- 提高了XML序列化器的性能
- 添加了序列化单个对象的能力(感谢dfeyer)
- 添加了cleanupParameters()方法以避免代码重复(感谢dfeyer)
- 添加了setFieldVisibility()方法,以便在索引和显示操作之间共享代码(感谢dfeyer)
- 添加了configureFields()方法,以便在索引和显示操作之间共享代码(感谢dfeyer)
- 修复了executeUpdate(),以便内容不是请求的参数,而是PUT请求的内容(感谢dfeyer)
- 修复了setFieldVisibility()方法,以便如果对象附加字段未在“get.display”选项中列出,则不会删除它们
- 使XML序列化器返回PHP数组(感谢dfeyer)
- 添加了
formats_strict
选项 - 改进了反序列化抽象
- 添加了 YAML 序列化器
- 改进了这些主题的文档
版本 0.9.3 - 2010-08-13
- 添加了
hide
和embedded_relations_hide
选项(感谢 Pascal Borreli) - 使字段过滤更快
版本 0.9.2 - 2010-07-01
- 添加了事件(感谢 Matthew Penrice)
- 添加了默认格式参数(感谢 Matthew Penrice)
- 添加了 PUT 支持
- 将默认序列化器切换为 json(更快且更简洁)
- 改进了文档
版本 0.9.1 - 2010-05-14
- 修复了上一版本中的拼写错误
版本 0.9 - 2010-05-14
- 添加了 JSON 序列化器。
版本 0.8 - 2010-05-09
- 首次公开发布。功能包括带有验证的 REST 模块生成和 XML 序列化器。