getpop / field-query
基于组件模型的PoP组件,组件化架构以此为基础
Requires
- php: ^8.0
- getpop/query-parsing: ^0.8.9
- getpop/translation: ^0.8.9
Requires (Dev)
- phpstan/phpstan: ^1.0
- phpunit/phpunit: >=9.3
- rector/rector: ^0.12
- squizlabs/php_codesniffer: ^3.0
Conflicts
- getpop/access-control: <0.8.9
- getpop/api: <0.8.9
- getpop/api-clients: <0.8.9
- getpop/api-endpoints: <0.8.9
- getpop/api-endpoints-for-wp: <0.8.9
- getpop/api-graphql: <0.8.9
- getpop/api-mirrorquery: <0.8.9
- getpop/api-rest: <0.8.9
- getpop/application: <0.8.9
- getpop/application-wp: <0.8.9
- getpop/cache-control: <0.8.9
- getpop/component-model: <0.8.9
- getpop/component-model-configuration: <0.8.9
- getpop/definitionpersistence: <0.8.9
- getpop/definitions: <0.8.9
- getpop/definitions-base36: <0.8.9
- getpop/definitions-emoji: <0.8.9
- getpop/engine: <0.8.9
- getpop/engine-wp: <0.8.9
- getpop/engine-wp-bootloader: <0.8.9
- getpop/filestore: <0.8.9
- getpop/function-fields: <0.8.9
- getpop/guzzle-helpers: <0.8.9
- getpop/hooks: <0.8.9
- getpop/hooks-wp: <0.8.9
- getpop/loosecontracts: <0.8.9
- getpop/mandatory-directives-by-configuration: <0.8.9
- getpop/modulerouting: <0.8.9
- getpop/multisite: <0.8.9
- getpop/resourceloader: <0.8.9
- getpop/resources: <0.8.9
- getpop/root: <0.8.9
- getpop/routing: <0.8.9
- getpop/routing-wp: <0.8.9
- getpop/site: <0.8.9
- getpop/site-builder-api: <0.8.9
- getpop/site-wp: <0.8.9
- getpop/spa: <0.8.9
- getpop/static-site-generator: <0.8.9
- getpop/translation-wp: <0.8.9
- graphql-api/extension-demo: <0.8.9
- graphql-api/external-dependency-wrappers: <0.8.9
- graphql-api/graphql-api-for-wp: <0.8.9
- graphql-api/markdown-convertor: <0.8.9
- graphql-by-pop/graphiql: <0.8.9
- graphql-by-pop/graphql-clients-for-wp: <0.8.9
- graphql-by-pop/graphql-endpoint-for-wp: <0.8.9
- graphql-by-pop/graphql-parser: <0.8.9
- graphql-by-pop/graphql-query: <0.8.9
- graphql-by-pop/graphql-request: <0.8.9
- graphql-by-pop/graphql-server: <0.8.9
- graphql-by-pop/graphql-voyager: <0.8.9
- pop-schema/block-metadata-for-wp: <0.8.9
- pop-schema/categories: <0.8.9
- pop-schema/categories-wp: <0.8.9
- pop-schema/comment-mutations: <0.8.9
- pop-schema/comment-mutations-wp: <0.8.9
- pop-schema/commentmeta: <0.8.9
- pop-schema/commentmeta-wp: <0.8.9
- pop-schema/comments: <0.8.9
- pop-schema/comments-wp: <0.8.9
- pop-schema/custompost-categories-wp: <0.8.9
- pop-schema/custompost-category-mutations: <0.8.9
- pop-schema/custompost-mutations: <0.8.9
- pop-schema/custompost-mutations-wp: <0.8.9
- pop-schema/custompost-tag-mutations: <0.8.9
- pop-schema/custompost-tags-wp: <0.8.9
- pop-schema/custompostmedia: <0.8.9
- pop-schema/custompostmedia-mutations: <0.8.9
- pop-schema/custompostmedia-mutations-wp: <0.8.9
- pop-schema/custompostmedia-wp: <0.8.9
- pop-schema/custompostmeta: <0.8.9
- pop-schema/custompostmeta-wp: <0.8.9
- pop-schema/customposts: <0.8.9
- pop-schema/customposts-wp: <0.8.9
- pop-schema/generic-customposts: <0.8.9
- pop-schema/media: <0.8.9
- pop-schema/media-wp: <0.8.9
- pop-schema/menus: <0.8.9
- pop-schema/menus-wp: <0.8.9
- pop-schema/meta: <0.8.9
- pop-schema/metaquery-wp: <0.8.9
- pop-schema/pages: <0.8.9
- pop-schema/pages-wp: <0.8.9
- pop-schema/post-categories: <0.8.9
- pop-schema/post-categories-wp: <0.8.9
- pop-schema/post-category-mutations: <0.8.9
- pop-schema/post-category-mutations-wp: <0.8.9
- pop-schema/post-mutations: <0.8.9
- pop-schema/post-tag-mutations: <0.8.9
- pop-schema/post-tag-mutations-wp: <0.8.9
- pop-schema/post-tags: <0.8.9
- pop-schema/post-tags-wp: <0.8.9
- pop-schema/postmedia-mutations: <0.8.9
- pop-schema/posts: <0.8.9
- pop-schema/posts-wp: <0.8.9
- pop-schema/queriedobject: <0.8.9
- pop-schema/queriedobject-wp: <0.8.9
- pop-schema/schema-commons: <0.8.9
- pop-schema/settings: <0.8.9
- pop-schema/settings-wp: <0.8.9
- pop-schema/tags: <0.8.9
- pop-schema/tags-wp: <0.8.9
- pop-schema/taxonomies: <0.8.9
- pop-schema/taxonomies-wp: <0.8.9
- pop-schema/taxonomymeta: <0.8.9
- pop-schema/taxonomymeta-wp: <0.8.9
- pop-schema/taxonomyquery: <0.8.9
- pop-schema/taxonomyquery-wp: <0.8.9
- pop-schema/user-avatars: <0.8.9
- pop-schema/user-avatars-wp: <0.8.9
- pop-schema/user-roles: <0.8.9
- pop-schema/user-roles-access-control: <0.8.9
- pop-schema/user-roles-acl: <0.8.9
- pop-schema/user-roles-wp: <0.8.9
- pop-schema/user-state: <0.8.9
- pop-schema/user-state-access-control: <0.8.9
- pop-schema/user-state-mutations: <0.8.9
- pop-schema/user-state-mutations-wp: <0.8.9
- pop-schema/user-state-wp: <0.8.9
- pop-schema/usermeta: <0.8.9
- pop-schema/usermeta-wp: <0.8.9
- pop-schema/users: <0.8.9
- pop-schema/users-wp: <0.8.9
- pop-sites-wassup/comment-mutations: <0.8.9
- pop-sites-wassup/contactus-mutations: <0.8.9
- pop-sites-wassup/contactuser-mutations: <0.8.9
- pop-sites-wassup/custompost-mutations: <0.8.9
- pop-sites-wassup/custompostlink-mutations: <0.8.9
- pop-sites-wassup/flag-mutations: <0.8.9
- pop-sites-wassup/form-mutations: <0.8.9
- pop-sites-wassup/gravityforms-mutations: <0.8.9
- pop-sites-wassup/highlight-mutations: <0.8.9
- pop-sites-wassup/newsletter-mutations: <0.8.9
- pop-sites-wassup/notification-mutations: <0.8.9
- pop-sites-wassup/post-mutations: <0.8.9
- pop-sites-wassup/postlink-mutations: <0.8.9
- pop-sites-wassup/share-mutations: <0.8.9
- pop-sites-wassup/socialnetwork-mutations: <0.8.9
- pop-sites-wassup/stance-mutations: <0.8.9
- pop-sites-wassup/system-mutations: <0.8.9
- pop-sites-wassup/user-state-mutations: <0.8.9
- pop-sites-wassup/volunteer-mutations: <0.8.9
- pop-wp-schema/comments: <0.8.9
- pop-wp-schema/customposts: <0.8.9
- pop-wp-schema/media: <0.8.9
- pop-wp-schema/menus: <0.8.9
- pop-wp-schema/pages: <0.8.9
- pop-wp-schema/posts: <0.8.9
- pop-wp-schema/schema-commons: <0.8.9
- pop-wp-schema/users: <0.8.9
README
通过URL参数查询GraphQL的语法,这使GraphQL API能够在服务器上缓存。
安装
通过Composer
composer require getpop/field-query
开发
源代码托管在PoP单仓库中,位于Engine/packages/field-query
。
使用方法
初始化组件
\PoP\Root\App::stockAndInitializeModuleClasses([([ \PoP\FieldQuery\Module::class, ]);
使用它
use PoP\FieldQuery\Facades\Query\FieldQueryInterpreterFacade; $fieldQueryInterpreter = FieldQueryInterpreterFacade::getInstance(); // To create a field from its elements $field = /* @todo Re-do this code! Left undone */ new Field($fieldName, $fieldArgs, $fieldAlias, $skipOutputIfNull, $fieldDirectives); // To retrieve the elements from a field $fieldName = $fieldQueryInterpreter->getFieldName($field); $fieldArgs = $fieldQueryInterpreter->getFieldArgs($field); // All other functions listed in FieldQueryInterpreterInterface // ...
原因
GraphQL查询通常跨越多行,它通过请求正文提供,而不是通过URL参数提供。因此,在服务器上难以缓存GraphQL查询的结果。为了支持GraphQL的服务器端缓存,我们可以尝试通过URL提供查询,以便使用基于URL作为其唯一ID的页面缓存标准机制。
本项目中描述和实现的语法是对GraphQL语法的重新构想,支持所有相同元素(字段参数、变量、别名、片段、指令等),但设计得易于编写、易于阅读和理解,以便在单行中传递,从而可以作为URL参数传递。
能够将查询作为URL参数传递具有其他几个优点
- 它消除了客户端库将GraphQL查询转换为所需格式(如Relay)的需求,从而提高了性能并减少了维护的代码量
- GraphQL API的消耗变得更简单(与REST相同),并且避免了依赖于特殊的客户端(如GraphiQL)来可视化查询结果
谁在使用它
PoP原生使用此语法:在应用程序本身中的每个组件中加载数据(如组件模型所做的那样),以及通过URL参数query
从API加载数据(如PoP API所做的那样)。
GraphQL服务器可以实现此语法以支持基于URI的服务器端缓存。为此,必须将查询从此语法转换为相应的GraphQL语法,然后将转换后的查询传递给GraphQL引擎。
语法
类似于GraphQL的查询描述了一组“字段”,其中每个字段可以包含以下元素
- 字段名称:要检索的数据
- 字段参数:如何过滤数据或格式化结果
- 字段别名:在响应中命名字段的方式
- 字段指令:更改执行操作的行为
与GraphQL不同,字段还可以包含以下元素
- 字段参数中的属性名称可能是可选的:简化向字段传递参数的过程
- 书签:保持从已定义的字段加载数据
- 运算符和助手:标准运算(如
and
、or
、if
、isNull
等)和环境变量访问助手(以及其他用例)可以作为字段存在 - 可组合字段:字段的响应可以作为另一个字段的输入,通过其参数或字段指令实现
- 如果为空则跳过输出:当字段值为空时忽略输出
- 可组合指令:指令可以修改其他嵌套指令的行为
- 表达式:在指令间传递值
从组成元素中,只有字段名是必须的;所有其他都是可选的。字段的组成顺序如下
- 字段名
- 参数:
(...)
- 书签:
[...]
- 别名:
@...
(如果书签也存在,它被放在里面) - 如果为空则跳过输出:
?
- 指令:指令名称和参数:
<directiveName(...)>
字段看起来是这样的
fieldName(fieldArgs)[@alias]?<fieldDirective(directiveArgs)>
为了更清楚地可视化,查询可以分成几行
fieldName( fieldArgs )[@alias]?< fieldDirective( directiveArgs ) >
注意
Firefox已经处理了多行查询:将其复制到地址栏中工作得非常好。要尝试它,复制https://newapi.getpop.org/api/graphql/
,然后按每个示例将查询复制到Firefox的地址栏中,voilà,查询应该会执行。Chrome和Safari表现不佳:它们需要在将查询粘贴到地址栏之前删除所有空格和换行符。
结论:使用Firefox!
要在同一查询中检索多个字段,请使用,
将它们连接起来
fieldName1@alias1,
fieldName2(
fieldArgs2
)[@alias2]?<
fieldDirective2
>
从节点检索属性
使用|
分隔要获取的属性。
In GraphQL:
query { id fullSchema }
In PoP (在浏览器中查看查询)
/?query= id| fullSchema
检索嵌套属性
要获取关系或嵌套数据,请使用.
描述到属性的路径。
In GraphQL:
query { posts { author { id } } }
In PoP (在浏览器中查看查询)
/?query= posts. author. id
当我们到达节点时,我们可以使用|
来获取多个属性
In GraphQL:
query { posts { author { id name url } } }
In PoP (在浏览器中查看查询)
/?query= posts. author. id| name| url
符号.
和|
可以混合使用,以获取路径上的属性
In GraphQL:
query { posts { id title author { id name url } } }
In PoP (在浏览器中查看查询)
/?query= posts. id| title| author. id| name| url
追加字段
通过使用,
将多个字段连接起来以组合它们。
In GraphQL:
query { posts { author { id name url } comments { id content } } }
In PoP (在浏览器中查看查询)
/?query= posts. author. id| name| url, posts. comments. id| content
按严格执行顺序追加字段
这是一个语法+功能特性。通过使用;
将多个字段连接起来,告诉数据加载引擎在解决左边的所有字段之后再解决;
右边的字段。
在GraphQL服务器中,之前的查询解析为这个(使用self
来延迟字段解析的时间)
In GraphQL:
query { posts { author { id name url } comments { id content } } }
In PoP (在浏览器中查看查询)
/?query= posts. author. id| name| url; posts. comments. id| content
在GraphQL服务器中,之前的查询解析为这个(使用self
来延迟字段解析的时间)
/?query= posts. author. id| name| url, self. self. posts. comments. id| content
字段参数
字段参数是一个属性数组,用于过滤结果(当应用于路径上的属性时)或修改输出(当应用于叶节点上的属性时)。这些被括号()
包围,使用:
定义属性名称和值(成为name:value
),并且使用,
分隔。
值不需要用引号"..."
括起来。
在GraphQL中过滤结果 (重要)
query { posts(filter:{ search: "template" }) { id title date } }
在PoP中过滤结果 (重要) (在浏览器中查看查询)
/?query=
posts(filter: { search: template }).
id|
title|
date
在GraphQL中格式化输出 (重要)
query { posts { id title dateStr(format: "d/m/Y") } }
在PoP中格式化输出 (重要) (在浏览器中查看查询)
/?query= posts. id| title| dateStr(format:d/m/Y)
字段参数中可选的属性名
如果可以从模式(例如,可以从模式定义中属性的位置推断出名称)中推断出参数名称,则可以忽略定义参数名称。
在PoP中 (在浏览器中查看查询)
/?query= posts. id| title| dateStr(d/m/Y)
别名
别名定义了输出字段的名称。别名名称必须以@
开头
In GraphQL:
query { posts { id title formattedDate: dateStr(format: "d/m/Y") } }
在PoP中 (在浏览器中查看查询)
/?query= posts. id| title| dateStr(d/m/Y)@formattedDate
请注意,与GraphQL不同,别名是可选的。在GraphQL中,因为字段参数不是响应中的字段的一部分,所以在查询具有不同参数的相同字段时,必须使用别名来区分它们。在PoP中,然而,字段参数是响应中的字段的一部分,这已经区分了字段。
In GraphQL:
query { posts { id title date: date formattedDate: dateStr(format: "d/m/Y") } }
在PoP中 (在浏览器中查看查询)
/?query=posts. id| title| dateStr| dateStr(d/m/Y)
书签
在GraphQL中遍历字段路径时,从不同的子分支加载数据具有视觉吸引力
In GraphQL:
query { users { posts { author { id name } comments { id content } } } }
然而,在PoP中,查询可能会变得非常冗长,因为在用,
组合字段时,它会从根开始再次遍历路径。
在PoP中 (在浏览器中查看查询)
/?query= users. posts. author. id| name, users. posts. comments. id| content
书签通过创建到路径的快捷方式来帮助解决这个问题,这样我们就可以方便地继续从该点加载数据。要定义书签,在遍历路径时,其名称用[...]
括起来,要使用它,其名称也用[...]
括起来。
在PoP中 (在浏览器中查看查询)
/?query= users. posts[userposts]. author. id| name, [userposts]. comments. id| content
带别名的书签
当我们需要定义到路径的书签和输出字段的别名时,这两个必须组合在一起:带有@
前缀的别名放置在书签分隔符[...]
内。
在PoP中 (在浏览器中查看查询)
/?query= users. posts[@userposts]. author. id| name, [userposts]. comments.id| content
变量
变量可以用于向字段参数输入值。在GraphQL中,解析到的值在体中定义(在查询的单独字典中),在PoP中,这些值从请求($_GET
或$_POST
)中检索。
变量名称必须以$
开头,其值在请求中可以定义在变量名称下,或者在variables
条目下,然后是变量名称。
API调用 在GraphQL中
{ "query":"query ($format: String) { posts { id title dateStr(format: $format) } }", "variables":"{ \"format\":\"d/m/Y\" }" }
1. /? format=d/m/Y& query= posts. id| title| dateStr($format) 2. /? variables[format]=d/m/Y& query= posts. id| title| dateStr($format)
片段
片段允许重用查询部分。类似于变量,它们的解析定义在请求中($_GET
或 $_POST
)。与 GraphQL 不同,片段不需要指明它操作的是哪种模式类型。
片段名称必须以 --
开头,它们解析的查询可以定义在片段名称下方,或者在 fragments
条目下方,然后是片段名称。
虽然片段可以包含 |
(用于拆分字段),但不能包含 ;
(用于拆分操作)或 ,
(用于拆分查询),以避免混淆(因为这些是从查询的根而不是片段计算出来的)。
In GraphQL:
query { users { ...userData posts { comments { author { ...userData } } } } } fragment userData on User { id name url }
1. /? userData= id| name| url& query= users. --userData| posts. comments. author. --userData 2. /? fragments[userData]= id| name| url& query= users. --userData| posts. comments. author. --userData
指令
指令可以修改执行获取数据操作的方式。每个字段都可以接受多个指令,每个指令都有自己的参数来定制其行为。指令集用 <...>
包围,其中的指令必须用 ,
分隔,它们的参数遵循与字段参数相同的语法:它们被 (...)
包围,其 name:value
对用 ,
分隔。
In GraphQL:
query { posts { id title featuredImage @include(if: $addFeaturedImage) { id src } } }
在 PoP 中(在浏览器中查看:查询 1,查询 2,查询 3,查询 4)
1. /? include=true& query= posts. id| title| featuredImage< include(if:$include) >. id| src 2. /? include=false& query= posts. id| title| featuredImage< include(if:$include) >. id| src 3. /? skip=true& query= posts. id| title| featuredImage< skip(if:$skip) >. id| src 4. /? skip=false& query= posts. id| title| featuredImage< skip(if:$skip) >. id| src
操作符和辅助函数
标准操作,如 and
、or
、if
、isNull
、contains
、sprintf
以及许多其他操作,可以作为字段在 API 中提供。然后,操作符名称代表字段名称,它可以接受相同格式的所有其他元素(参数、别名等)。
要作为数组传递参数值,我们将其括在 []
中,并用 ,
分隔其项。格式可以是只是 value
(数字数组)或 key:value
(索引数组)。
在 PoP 中(在浏览器中查看:查询 1,查询 2,查询 3,查询 4,查询 5,查询 6,查询 7,查询 8,查询 9)
1. /?query=not(true) 2. /?query=or([1, 0]) 3. /?query=and([1, 0]) 4. /?query=if(true, Show this text, Hide this text) 5. /?query=equals(first text, second text) 6. /?query=isNull(),isNull(something) 7. /?query=sprintf( %s is %s, [ PoP API, cool ]) 8. /?query=echo([ name: PoP API, status: cool ]) 9. /?query=arrayValues([ name: PoP API, status: cool ])
同样,辅助函数可以提供所需的所有信息,也作为字段行为。例如,辅助函数 context
提供系统状态中的值,辅助函数 var
可以从系统状态中检索任何特定变量。
1. /?query=context 2. /?query= var(route)| var(target)@target| var(datastructure)
可组合字段
当操作符能够接收字段输出作为其输入时,从拥有操作符中获得的真正好处。由于操作符本身就是一个字段,这可以概括为“可组合字段”:将任何字段的输出作为另一个字段的参数值传递。
为了区分字段输入是字符串还是字段名,字段必须具有字段参数括号 (...)
(如果没有参数,则简单地 ()
)。例如,"id"
表示字符串 "id",而 "id()"
表示执行并传递字段 "id" 的结果。
在PoP中(在浏览器中查看:查询1,查询2,查询3,查询4,查询5,查询6)
1. /?query= posts. hasComments| not(hasComments()) 2. /?query= posts. hasComments| hasFeaturedImage| or([ hasComments(), hasFeaturedImage() ]) 3. /?query= var(fetching-site)| posts. hasFeaturedImage| and([ hasFeaturedImage(), var(fetching-site) ]) 4. /?query= posts. if ( hasComments(), sprintf( Post with title '%s' has %s comments, [ title(), commentCount() ]), sprintf( Post with ID %s was created on %s, [ id(), dateStr(d/m/Y) ]) )@postDesc 5. /?query=users. name| equals( name(), leo ) 6. /?query= posts. featuredImage| isNull(featuredImage())
为了将 (
和 )
作为查询字符串的一部分包含,并避免将其视为要执行的字段,我们必须用引号括起来:"..."
。
在PoP中(在浏览器中查看查询)
/?query= posts. sprintf( "This post has %s comment(s)", [ commentCount() ])@postDesc
带有指令的可组合字段
可组合字段允许对查询对象本身执行操作。利用这一功能,PoP中的指令变得非常有用,因为它们可以独立地对每个对象进行条件评估。此功能可以引发大量新功能,例如客户端内容操作、精细访问控制、增强验证等。
例如,GraphQL规范 要求 支持指令 include
和 skip
,它们接收一个带有布尔值的参数 if
。虽然GraphQL期望此值通过变量提供(如上节指令所示),但在PoP中可以从对象中检索。
1. /?query= posts. id| title| featuredImage< include(if:not(isNull(featuredImage()))) >. id| src 2. /?query= posts. id| title| featuredImage< skip(if:isNull(featuredImage())) >. id| src
如果为空则跳过输出
每当字段的值是null时,其嵌套字段将不会被检索。例如,考虑以下情况,其中字段 "featuredImage"
有时是null
在PoP中(在浏览器中查看)
/?query= posts. id| title| featuredImage. id| src
如上节指令式组合字段中所示,通过结合指令include
和skip
与组合字段,我们可以决定当字段值为null时不输出该字段。然而,执行此行为的查询在查询路径中间添加了一个指令,使得查询非常冗长且可读性差。由于这是一个非常常见的用例,因此将其通用化并将简化的版本纳入语法中是有意义的。
为此,PoP引入了符号?
,将其放置在字段名(及其字段参数、别名和书签)之后,以表示“如果此值是null,则不输出它”。
在PoP中 (在浏览器中查看查询)
/?query=
posts.
id|
title|
featuredImage?.
id|
src
组合指令和表达式
指令可以嵌套:外部指令可以修改其内部嵌套指令的行为。它可以通过“表达式”将值传递给其组合指令,这些表达式是带有%...%
的变量,可以在运行时创建(作为查询的一部分编写),也可以在指令本身中定义。
以下示例中,指令<forEach>
遍历数组的元素,对每个元素执行组合指令<applyFunction>
的操作。它通过预定义表达式%{value}%
(在指令内编写)传递数组项。
在PoP中 (在浏览器中查看查询)
/?query= echo([ [banana, apple], [strawberry, grape, melon] ])@fruitJoin< forEach< applyFunction( function: arrayJoin, addArguments: [ array: %{value}%, separator: "---" ] ) > >
以下示例中,指令<advancePointerInArrayOrObject>
通过表达式%{toLang}%
(即时定义)将语言传递给指令<translate>
,以表示要翻译到的语言。
在PoP中 (在浏览器中查看查询)
/?query= echo([ { text: Hello my friends, translateTo: fr }, { text: How do you like this software so far?, translateTo: es } ])@translated< forEach< advancePointerInArrayOrObject( path: text, appendExpressions: { toLang:extract(%{value}%,translateTo) } )< translateMultiple( from: en, to: %{toLang}%, oneLanguagePerField: true ) > > >
组合元素
可以组合不同的元素,以下是一些示例。
一个片段可以包含嵌套路径、变量、指令和其他片段
在PoP中 (在浏览器中查看查询)
/? postData= id| title| --nestedPostData| dateStr(format:$format)& nestedPostData= comments< include(if:$include) >. id| content& format=d/m/Y& include=true& limit=3& order=title& query= posts( pagination: { limit:$limit }, sort: { order:$order } ). --postData| author. posts( pagination: { limit:$limit } ). --postData
一个片段可以包含指令,这些指令被传递到片段解析字段中
在PoP中 (在浏览器中查看查询)
/? fragments[props]= title| date& query= posts. id| --props< include(if:hasComments()) >
如果片段解析字段中的字段已经有自己的指令,则应用这些指令;否则,应用片段定义中的指令
在PoP中 (在浏览器中查看查询)
/? fragments[props]= title| url< include(if:not(hasComments())) >& query= posts. id| --props< include(if:hasComments()) >
一个片段可以包含别名,然后将其传递到所有片段解析字段作为枚举别名(例如@aliasName1
,@aliasName2
等)
在PoP中 (在浏览器中查看查询)
/? fragments[props]= title| url| featuredImage& query= posts. id| --props@prop
一个片段可以包含“如果为null则跳过输出”符号,然后将其传递到所有片段解析字段
在PoP中 (在浏览器中查看查询)
/? fragments[props]= title| url| featuredImage& query= posts. id| --props?
将指令和跳过输出如果为null符号与片段结合
在PoP (在浏览器中查看查询)
/? fragments[props]= title| url< include(if:hasComments()) >| featuredImage& query= posts. id| hasComments| --props?< include(if:hasComments()) >
PHP版本
需求
- 开发需要PHP 8.1+
- 生产需要PHP 7.1+
支持的PHP特性
查看leoloso/PoP
中支持的PHP特性列表(链接)
预览降级到PHP 7.1
通过Rector(dry-run模式)
composer preview-code-downgrade
标准
PSR-1、PSR-4 和 PSR-12。
要检查编码标准,运行PHP CodeSniffer
composer check-style
要自动修复问题,运行
composer fix-style
变更日志
请参阅CHANGELOG了解最近更改的详细信息。
测试
$ composer test
报告问题
要报告错误或请求新功能,请在PoP monorepo问题跟踪器上操作。
贡献
我们欢迎对这个包的贡献,可以在PoP monorepo(这个包的源代码托管的地方)进行。
请参阅CONTRIBUTING和CODE_OF_CONDUCT以获取详细信息。
安全性
如果您发现任何安全问题,请通过电子邮件leo@getpop.org发送,而不是使用问题跟踪器。
鸣谢
许可证
GNU通用公共许可证v2(或更高版本)。请参阅许可证文件以获取更多信息。