pimcore-graphql使用文档
Pimcore Datahub GraphQL 使用文档
参考官方文档:https://docs.pimcore.com/platform/Datahub/GraphQL/ (文档版本 2026.3)
适用组件:Pimcore Datahub(GraphQL 端点)
说明:本文基于官方文档整理,结合示例给出可直接套用的查询/变更写法。部分说明(如SQL Condition移除)与 Datahub 2.0.0+ 行为一致。
1. 概述
Pimcore Datahub 通过 GraphQL 端点 把 Pimcore 的数据(Data Object、Asset、Document)以 GraphQL 方式对外暴露,方便与其他系统集成。
- 每个端点在 Datahub 配置面板里创建与管理。
- Datahub 会为端点自动生成 GraphQL Schema,可借助内置的 GraphQL Playground 直接调试。
- 端点地址本身即对外 API(不是 配置面板使用的 Studio API)。
核心能力一览:
| 能力 | 说明 |
|---|---|
| 查询(Query) | 读取 Data Object / Asset / Document,支持过滤、排序、分页、本地化 |
| 变更(Mutation) | 创建 / 更新 / 删除 Data Object / Asset / Document |
| 操作符(Operator) | 在字段暴露前对数据做格式化 / 转换 |
| 事件(Event) | 基于 Symfony EventDispatcher 在执行前后做定制 |
| 输出缓存 | 用 Pimcore 默认缓存后端缓存响应,提升复杂查询性能 |
2. 端点与访问方式
2.1 标准端点
/pimcore-graphql-webservices/{configurationname}?apikey={yourApiKey}
例如配置名为 blogdemo、apikey 为 123456,则端点为:
/pimcore-graphql-webservices/blogdemo?apikey=123456
2.2 调试入口
在配置面板底部点击 Open in tab 按钮,即可在新标签打开该端点的 GraphQL Playground:左侧写查询,右侧看结果。
2.3 自定义端点 URL
可在 app/config/routing.yml 中覆盖默认路由(同时覆盖 explorer 与 webservice):
# 修改 explorer 访问路径
admin_pimcoredatahub_config:
path: /pimcore-datahub-webservices-my-endpoint/explorer/{clientname}
defaults: { _controller: Pimcore\Bundle\DataHubBundle\Controller\GraphQLExplorerController::explorerAction }
# 修改 webservice 端点路径
admin_pimcoredatahub_webservice:
path: /pimcore-graphql-webservices-my-endpoint/{clientname}
defaults: { _controller: Pimcore\Bundle\DataHubBundle\Controller\WebserviceController::webonyxAction }
3. 端点配置
配置入口在 Datahub 配置面板,分为 General / Schema / Security / Custom Permissions 四个部分。
3.1 通用设置(General Settings)
| 字段 | 说明 |
|---|---|
Active |
启用 / 停用该配置,只有激活的配置才会响应请求 |
Type / Name |
创建时设定,此处只读 |
Description |
端点说明(自由文本) |
Group |
在 Datahub 左侧树中给配置分组 |
⚠️
SQL Condition字段已在 Datahub 2.0.0 中移除。如需限制 Data Object 的查询结果范围,请改用 Workspace Settings(见 3.3)。
3.2 Schema 设置(Schema Settings)
决定哪些数据实体通过端点暴露。
- Query Schema:勾选要暴露的 Data Object Class,并通过字段配置选择要输出的字段。
- Mutation Schema:决定该 Class 是否允许通过端点 Create / Update / Delete。
- Generic Types:定义哪些数据类型可通过端点被创建 / 读取 / 更新 / 删除。
字段配置(Available Fields Configuration):
- 在 Query/Mutation Schema 区域,右键字段的
Settings图标(齿轮),选择 Add 添加实体。 - 在弹出的字段配置窗口中,选择要暴露的具体字段。
- 可叠加 Operator(见第 7 节)对字段做转换。
- ⚠️ 并非所有数据类型都受支持;若尝试添加不支持的类型,界面会给出提示。
3.3 安全设置(Security Settings)
认证(Authentication)
- 当前支持 API Key 方式:每次请求都必须携带。
- 点击 Generate Key 生成密钥,可生成多个并并存于 Datahub API Keys 列表。
- Skip Permission Check:打开后完全跳过 workspace 权限检查(慎用)。
Introspection(自省)
- 默认开启,开启后端点会暴露 Schema 定义,GraphiQL 等工具可据此提供自动补全与文档。
- 关闭方式(任选其一):
- 配置面板勾选 Disable Introspection;
- 或在 Symfony 配置中:
pimcore_data_hub:
graphql:
allow_introspection: false
Workspace Settings
- 定义端点可访问的数据范围(与 Pimcore 用户的 workspace 权限类似)。
- ⚠️ 若不选择任何 workspace,则 没有任何目录可访问。
- 可用权限:
Create/Read/Update/Delete。
错误处理策略(关联对象不可见时)
默认行为:关联/相关的 object、document、asset 若对端点不可见,则直接置空(null)。
通过 Symfony 配置可切换:
pimcore_data_hub:
graphql:
not_allowed_policy: 2 # 1 = 整个查询失败;2 = 置空/对多关联跳过(默认)
3.4 自定义权限(Custom Permissions)
当自定义查询或扩展 Datahub 时,可能需要为某些数据实体增加额外权限(类似 Documents/Assets 的读写控制)。
通过监听 Pimcore\Bundle\DataHubBundle\ConfigEvents::SPECIAL_ENTITIES 事件添加:
use Pimcore\Bundle\DataHubBundle\ConfigEvents;
use Pimcore\Bundle\DataHubBundle\Event\Config\SpecialEntitiesEvent;
use Pimcore\Bundle\DataHubBundle\Model\SpecialEntitySetting;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class GraphQlCustomListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [ConfigEvents::SPECIAL_ENTITIES => 'specialEntities'];
}
public function specialEntities(SpecialEntitiesEvent $event)
{
$custom = new SpecialEntitySetting(
'custom', // 实体名
true, true, true, false, // read/create/update/delete 是否可选
$event->getConfig()['schema']['specialEntities']['custom']['read'] ?? false,
$event->getConfig()['schema']['specialEntities']['custom']['create'] ?? false,
$event->getConfig()['schema']['specialEntities']['custom']['update'] ?? false,
$event->getConfig()['schema']['specialEntities']['custom']['delete'] ?? false
);
$event->addSpecialSetting($custom);
}
}
权限开关含义:* Possible 控制界面是否出现该复选框;* Allowed 设定默认值。
4. 查询(Query)
💡 所有端点都基于自动生成的 Schema,先看对应端点的 Schema 再写查询最准确。
4.1 Data Object 查询
支持的常用数据类型(节选,完整列表见官方文档):
Advanced Many-to-Many Relation、Block、Checkbox、Classification Store、Country/Countries、Date/DateTime、Email、Field-Collections、Geopoint/Geobounds/Geopolygon、Image、Input、Language/Languages、Link、Many-to-One / Many-to-Many Relation、Multiselect、Numeric、Quantity Value、Select、Slider、Table、Textarea、URL Slug、Video、Wysiwyg 等。
(1) 取单条对象
{
getNews(id: 4) {
id
title
}
}
(2) 取列表(按 ID 限制)
{
getNewsListing(ids: "4,5") {
edges {
node { id }
}
}
}
(3) 取列表(按 fullpath 限制)
{
getNewsListing(fullpaths: "/NewsArticle,/NewsArticle2") {
totalCount
edges {
node { id }
}
}
}
当 fullpath 本身含逗号时,用单引号包裹避免被当作分隔符:
fullpaths: "'/NewsArticle,Headline','/NewsArticle2'"
4.2 Document 查询
支持的文档类型:Email、Hardlink、Link、Page、Snippet。
支持的页面元素类型(节选):Areablock、Checkbox、Date、Embed、Image、Input、Link、Multiselect、Numeric、Pdf、Relation(s)、Renderlet、Scheduled Block、Select、Table、Textarea、Video、Wysiwyg。
取页面文档并读取 Date 元素
{
getDocument(id: 25) {
... on document_page {
fullpath
editables {
...on document_editableDate {
_editableName
timestamp
formatted(format:"Y-m-d")
}
}
}
}
}
读取继承的可编辑内容
{
getDocument(id: 207) {
... on document_page {
id
editables(getInheritedValues: true) {
__typename
}
}
}
}
读取 Wysiwyg 内容(text = 原始 HTML;frontend = 经 Pimcore 处理、链接重写后的 HTML)
{
getDocument(id: 207) {
... on document_page {
id
editables(getInheritedValues: true) {
__typename
...on document_editableWysiwyg {
text
frontend
}
}
}
}
}
获取整页渲染结果(rendered 字段)
{
getDocument(id: 207) {
... on document_page {
id
rendered(
attributes: [{key: "myControllerAttributeName", value: "Hello World!"}],
use_layout: true,
options: [{key: "ignore_errors", value: "1"}]
)
}
}
}
读取翻译链接
{
getDocument(id: 76) {
... on document_page {
id
translations {
id
language
target {
... on document_headlessdocument { fullpath }
}
}
}
}
}
4.3 Asset 查询
支持单个 Asset、单个 Asset 文件夹、Asset 列表的查询。
取单个 Asset
{
getAsset(id: 4) {
id
filename
fullpath
}
}
取单个 Asset 文件夹
{
getAssetFolder(id: 4) {
id
fullpath
}
}
取 Asset 列表
{
getAssetListing(ids: "4,5") {
edges { node { id } }
}
}
缩略图(Image / Video)
# 图片缩略图,deferred 可延迟到首次访问时生成
query {
getAsset(id: 289) {
id
thumbnail: fullpath(thumbnail: "events_header", deferred: true)
}
}
# 视频缩略图,可指定 format
query {
getAsset(id: 353) {
id
thumbnail: fullpath(thumbnail: "content")
}
}
5. 过滤、排序、分页(Listings)
5.1 过滤(Filtering)
使用 Pimcore webservice filter 语法(JSON 字符串形式传入 filter 参数)。
{
getManufacturerListing(filter: "{\"name\": {\"$like\" :\"%ca%\"}}") {
edges {
node { id name }
}
totalCount
}
}
返回:
{
"data": {
"getManufacturerListing": {
"edges": [
{ "node": { "id": "45", "name": "Cadillac" } },
{ "node": { "id": "80", "name": "AC Cars" } },
{ "node": { "id": "153", "name": "MG Cars" } }
],
"totalCount": 3
}
}
}
支持
=、!=、>、<、$like、$in等运算符,可通过 AND/OR 组合。详见官方 Filtering 文档。
5.2 排序(Sorting)
{
getManufacturerListing(sortBy: "name", sortOrder: "DESC") {
edges { node { id name } }
}
}
5.3 分页(Pagination)
first= 限制条数(limit)after= 偏移量(offset)
{
getManufacturerListing(first: 3, after: 1) {
edges {
node { id name }
}
}
}
6. 本地化(Localization)
6.1 默认语言
查询时传入 defaultLanguage 改变本地化字段的默认取值语言:
{
getNewsListing(defaultLanguage: "de") {
edges { node { id title } }
}
}
6.2 字段级语言
可为单个字段单独指定语言:
{
getUser(id: 50, defaultLanguage: "en") {
myAdvancedObjects {
element {
id
title
deTitle: title(language: "de")
shortText(language: "de")
}
}
}
}
6.3 关闭回退语言
默认会回退到 fallback 语言取值,可关闭:
query {
getCar(id: 1229) {
name(language:"de", getFallbackLanguageValue:false)
}
}
7. 操作符(Operators)
Operator 用于在数据离开 Pimcore(查询)或写入 Pimcore(变更)前,对字段做 格式化 / 转换。
位置:在 Schema Definition 选项卡的 Query Schema 或 Mutation Schema 区域,点击齿轮打开字段配置对话框。
- 左侧 Available Fields 列出已暴露字段。
- 右侧图标条分组提供 Operator:Query Schema 提供 Formatter / Transformer / Other;Mutation Schema 仅提供 Other。
- 把 Operator 拖到 Available Fields 侧即可添加,按 Operator 类型填写参数对话框;添加后把字段拖到 Operator 之下使其生效。
各 Operator 的具体参数与用法见官方 Operators 章节(如 concat、thumbnail、absolutePath、translateValue、alias 等)。
8. 变更(Mutation)
⚠️ 变更要求端点开启对应 Write 权限,且配置中启用了该 mutation。
⚠️ 通过端点删除的 Data Object 会在 Pimcore 中被 永久删除。
提示:Create / Update 可在同一请求里直接取回更新后的数据。
8.1 Data Object 变更
创建对象
mutation {
createNews(parentId: 429, key: "news_created_by_gql", published: false) {
success
message
output(defaultLanguage: "de") {
id
creationDate
fullpath
title(language: "en")
}
}
}
更新对象
mutation {
updateNews(id: 1196, defaultLanguage: "de", input: {
title: "german TITLE",
shortText: "new short text"
}) {
success
output {
modificationDate
title
}
}
}
删除对象
mutation {
deleteNews(id: 1196) {
success
message
}
}
创建/更新关联关系、Fieldcollection 变更等进阶示例见官方 Mutation Samples。
8.2 Asset 变更
创建 Asset(data 为 Base64 编码的文件内容)
mutation {
createAsset(
parentId: 1,
filename: "foo.png",
type: "image",
input: {
data: "ewogICAgImZpZWxkY29sbGVjdGlvbiI6IFsKICAgICAgICB7..."
}) {
success
message
}
}
父节点必须被端点的 workspace 的
create权限覆盖;input里指定的parentId同样受此约束。
更新 Asset(重命名 + 更新数据)
mutation {
updateAsset(id: 76, input: {filename:"newfilename", data:"iVBORw0KGgoAAAANSUhEUg....."}) {
success
message
assetData { modificationDate }
}
}
目标 Asset 需有
update权限;若input含新parentId,还需该新父节点有create权限,否则返回success: false。
删除 Asset
mutation {
deleteAsset(id: 533) { success message }
}
# 或按 fullpath 删除
mutation {
deleteAsset(fullpath: "/Sample Content/Background Images/foo.png") { success message }
}
8.3 Document 变更
支持的文档类型:Email、Link、Page 等。
支持的页面元素类型(节选):Areablock、Block、Embed、Image(仅 target asset + alt text,暂无 hotspot/marker)、Input、Multiselect、Scheduled Block、Select、Wysiwyg。
文档变更有两种模式:
模式 A:Free-form API(自由表单)
需了解 Pimcore 的 editable 命名策略,直接按名称更新单个/多个 editable。
mutation {
updateDocumentPage(
id: 99
input: {
editableUpdateStrategy: replaceAll # 默认 update
editables: {
input: [
{ _editableName: "content:2.headline", text: "HEYYOU 3" }
{ _editableName: "headline", text: "NEW 2" }
]
wysiwyg: [
{ _editableName: "content:1.content", text: "my new <b>wysiwyg</b>" }
]
}
module: "mymodule"
}
) {
success
document { controller }
}
}
模式 B:Tree API(树状嵌套,推荐)
不熟悉 editable 命名策略时使用,层级嵌套更直观。
mutation {
updateDocumentPage(
id: 99
input: {
editables: {
areablock: [
{
_editableName: "content"
items: [
{
type: "headlines"
editables: {
input: [
{ _editableName: "headline", text: "HEY, I AM A SUBHEADLINE" }
]
}
}
]
}
]
}
controller: "@AppBundle\\Controller\\ContentController"
action: "default"
}
) {
success
document { controller elements { __typename } }
}
}
9. 输出缓存(Output Cache)
可缓存端点响应,使用 Pimcore 默认缓存后端(Doctrine / Redis 等),对复杂、多依赖的响应提速明显。
#### DATAHUB OUTPUT CACHE
pimcore_data_hub:
graphql:
output_cache_enabled: false # 总开关,默认关闭
output_cache_lifetime: 20 # 每个响应缓存秒数,默认 30(启用但未设置时)
单次请求禁用缓存(仅 DEBUG 模式):在 URL 追加 ?pimcore_outputfilters_disabled=true。
自定义缓存行为:通过 Event Listener(见第 10 节 OutputCacheEvents)定制,例如按请求条件开关缓存、修改待缓存响应。
10. 事件(Events)
Datahub GraphQL 事件基于 Symfony EventDispatcher,在 Query / Mutation 执行过程中触发。
事件常量定义所在类:
- Query:
...Event\GraphQL\QueryEvents - Mutation:
...Event\GraphQL\MutationEvents - Executor:
...Event\GraphQL\ExecutorEvents - Listing:
...Event\GraphQL\ListingEvents - Output Cache:
...Event\GraphQL\OutputCacheEvents
注册方式(Event Subscriber,需 autoconfigure: true):
services:
_defaults:
autoconfigure: true
AppBundle\EventListener\:
resource: '../../EventListener'
示例 1:Query / Mutation 执行前后
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\ExecutorEvents;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\ExecutorEvent;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\ExecutorResultEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class GraphQlSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
ExecutorEvents::PRE_EXECUTE => 'onPreExecute',
ExecutorEvents::POST_EXECUTE => 'onPostExecute',
];
}
public function onPreExecute(ExecutorEvent $event)
{
$query = $event->getQuery();
$schema = $event->getSchema();
}
public function onPostExecute(ExecutorResultEvent $event)
{
$result = $event->getResult();
}
}
示例 2:绕过 workspace 权限
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\MutationEvents;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\MutationTypeEvent;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\QueryTypeEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class GraphQlSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
MutationEvents::PRE_BUILD => 'onMutationPreBuild',
QueryEvents::PRE_BUILD => 'onQueryPreBuild',
];
}
public function onMutationPreBuild(MutationTypeEvent $event)
{
$event->getMutationType()->setOmitPermissionCheck(true);
}
public function onQueryPreBuild(QueryTypeEvent $event)
{
$event->getQueryType()->setOmitPermissionCheck(true);
}
}
示例 3:为已有类型追加自定义参数
use GraphQL\Type\Definition\Type;
// 监听 MutationEvents::POST_BUILD / QueryEvents::POST_BUILD
public function onQueryPostBuild(QueryTypeEvent $event)
{
$config = $event->getConfig();
$config['fields']['getProductListing']['args']['foo'] = [
'type' => Type::boolean()
];
$event->setConfig($config);
}
示例 4:为对象列表追加自定义查询条件
use Pimcore\Model\DataObject\Service;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\ListingEvents;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\ListingEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class GraphQlSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [ListingEvents::PRE_LOAD => 'onListingPreLoad'];
}
public function onListingPreLoad(ListingEvent $event)
{
$listing = $event->getListing();
if ($listing->getClassName() === 'Product') {
$listing->setCondition(sprintf(
'(%s IN (SELECT %s FROM objects WHERE %s=\'object\') AND %s = \'variant\')',
Service::getVersionDependentDatabaseColumnName('o_parentid'),
Service::getVersionDependentDatabaseColumnName('o_id'),
Service::getVersionDependentDatabaseColumnName('o_type'),
Service::getVersionDependentDatabaseColumnName('o_type')
));
}
$event->setListing($listing);
}
}
示例 5:按请求条件开关输出缓存
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\OutputCachePreLoadEvent;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\OutputCachePreSaveEvent;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\OutputCacheEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class GraphqlListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
OutputCacheEvents::PRE_LOAD => 'onPreLoadCache',
OutputCacheEvents::PRE_SAVE => 'onPreSaveCache',
];
}
public function onPreLoadCache(OutputCachePreLoadEvent $event)
{
if (str_contains($event->getRequest()->getMethod(), "my-special-endpoint")) {
$event->setUseCache(false);
}
}
public function onPreSaveCache(OutputCachePreSaveEvent $event)
{
if (str_contains($event->getRequest()->getMethod(), "my-awesome-endpoint")) {
$response = $event->getResponse();
// 修改待缓存响应...
$event->setResponse($response);
}
}
}
注:
OutputCacheEvents::PRE_LOAD在尝试从缓存读取前触发;PRE_SAVE在写入缓存前触发(CORS 等不可缓存头会在保存前移除、加载后再加回)。
11. 调试小技巧
- GraphQL Playground 中调试 Xdebug:打开设置,将
request.credentials改为include,否则XDEBUG_SESSIONCookie 头会被默认移除。 - 准确写查询的前提:始终先看目标端点的 Schema(通过 Playground 的 Docs 面板或 introspection 输出)。
- 关联数据不可见:默认置空;如需让整个查询失败,改
not_allowed_policy: 1。
12. 快速上手清单
- 在 Datahub 新建 GraphQL 配置,General 中激活并命名。
- Schema 中勾选要暴露的 Data Object Class / Document / Asset,并选择字段。
- Security 中生成 API Key,配置 Workspace 限定可访问范围;按需关闭 Introspection。
- 通过
Open in tab打开 Playground,用 introspection 查看自动生成的 Schema。 - 编写 Query / Mutation,先用 Playground 验证,再接入外部系统。
- 如需性能优化,开启 Output Cache;如需深度定制,使用 Events。
附录:官方文档导航
QQ二群 166427999
如果项目有技术瓶颈问题,请联系↓↓
QQ: 903464207
微信: zx903464207
浙公网安备 33010602011771号