mirror of
https://github.com/strapi/strapi.git
synced 2025-08-19 06:08:50 +00:00
415 lines
52 KiB
HTML
415 lines
52 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en-US">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>GraphQL | Strapi Docs</title>
|
|
<meta name="description" content="API creation made simple, secure and fast.">
|
|
|
|
|
|
<link rel="preload" href="/documentation/assets/css/styles.a8210063.css" as="style"><link rel="preload" href="/documentation/assets/js/app.a8210063.js" as="script"><link rel="preload" href="/documentation/assets/js/45.6746c3dc.js" as="script"><link rel="prefetch" href="/documentation/assets/js/28.9b077c15.js"><link rel="prefetch" href="/documentation/assets/css/1.styles.77d89b12.css"><link rel="prefetch" href="/documentation/assets/js/1.77d89b12.js"><link rel="prefetch" href="/documentation/assets/css/2.styles.08038ddb.css"><link rel="prefetch" href="/documentation/assets/js/2.08038ddb.js"><link rel="prefetch" href="/documentation/assets/js/3.4d92d5e3.js"><link rel="prefetch" href="/documentation/assets/js/4.385ae6a0.js"><link rel="prefetch" href="/documentation/assets/js/5.edd21cb3.js"><link rel="prefetch" href="/documentation/assets/js/6.fd6e4b24.js"><link rel="prefetch" href="/documentation/assets/js/7.e1f45fa9.js"><link rel="prefetch" href="/documentation/assets/js/8.dc78e1c2.js"><link rel="prefetch" href="/documentation/assets/js/9.fd6a21e6.js"><link rel="prefetch" href="/documentation/assets/js/10.f9e7d997.js"><link rel="prefetch" href="/documentation/assets/js/11.bfb9de0f.js"><link rel="prefetch" href="/documentation/assets/js/12.124227d1.js"><link rel="prefetch" href="/documentation/assets/js/13.d8092700.js"><link rel="prefetch" href="/documentation/assets/js/14.7cfd4cb8.js"><link rel="prefetch" href="/documentation/assets/js/15.55a20f7c.js"><link rel="prefetch" href="/documentation/assets/js/16.5c84c402.js"><link rel="prefetch" href="/documentation/assets/js/17.1c93d494.js"><link rel="prefetch" href="/documentation/assets/js/18.e1f1758f.js"><link rel="prefetch" href="/documentation/assets/js/19.8d1b00cd.js"><link rel="prefetch" href="/documentation/assets/js/20.856d7bdd.js"><link rel="prefetch" href="/documentation/assets/js/21.6f851286.js"><link rel="prefetch" href="/documentation/assets/js/22.7ddb4e1d.js"><link rel="prefetch" href="/documentation/assets/js/23.15e5a0c3.js"><link rel="prefetch" href="/documentation/assets/js/24.6fdf34d0.js"><link rel="prefetch" href="/documentation/assets/js/25.21c9a549.js"><link rel="prefetch" href="/documentation/assets/js/26.6608295c.js"><link rel="prefetch" href="/documentation/assets/js/27.2c9596ea.js"><link rel="prefetch" href="/documentation/assets/js/29.8ea8ecc1.js"><link rel="prefetch" href="/documentation/assets/js/30.5d2829b8.js"><link rel="prefetch" href="/documentation/assets/js/31.fad00a3a.js"><link rel="prefetch" href="/documentation/assets/js/32.a6900221.js"><link rel="prefetch" href="/documentation/assets/js/33.bbfb3084.js"><link rel="prefetch" href="/documentation/assets/js/34.0eb2f8aa.js"><link rel="prefetch" href="/documentation/assets/js/35.76c29241.js"><link rel="prefetch" href="/documentation/assets/js/36.dfcc07a1.js"><link rel="prefetch" href="/documentation/assets/js/37.173a8112.js"><link rel="prefetch" href="/documentation/assets/js/38.b86fac79.js"><link rel="prefetch" href="/documentation/assets/js/39.a7d50afe.js"><link rel="prefetch" href="/documentation/assets/js/40.0415492d.js"><link rel="prefetch" href="/documentation/assets/js/41.5ef681df.js"><link rel="prefetch" href="/documentation/assets/js/42.fdd80522.js"><link rel="prefetch" href="/documentation/assets/js/43.03b496f2.js"><link rel="prefetch" href="/documentation/assets/js/44.3f55a367.js"><link rel="prefetch" href="/documentation/assets/js/46.ff6bc353.js"><link rel="prefetch" href="/documentation/assets/js/47.53b7147a.js"><link rel="prefetch" href="/documentation/assets/js/48.31a883aa.js"><link rel="prefetch" href="/documentation/assets/js/49.18bd1a60.js"><link rel="prefetch" href="/documentation/assets/js/50.9b6079cd.js"><link rel="prefetch" href="/documentation/assets/js/51.b67aee1b.js"><link rel="prefetch" href="/documentation/assets/js/52.62bc63b6.js"><link rel="prefetch" href="/documentation/assets/js/53.2c567c55.js"><link rel="prefetch" href="/documentation/assets/js/54.6cc10d25.js"><link rel="prefetch" href="/documentation/assets/js/55.7faca13f.js"><link rel="prefetch" href="/documentation/assets/js/56.0b06ad54.js"><link rel="prefetch" href="/documentation/assets/js/57.a87c48df.js"><link rel="prefetch" href="/documentation/assets/js/58.1c6547d9.js"><link rel="prefetch" href="/documentation/assets/js/59.06f908d7.js"><link rel="prefetch" href="/documentation/assets/js/60.b5156b8d.js"><link rel="prefetch" href="/documentation/assets/js/61.1d5cafa9.js"><link rel="prefetch" href="/documentation/assets/js/62.ccacebe2.js"><link rel="prefetch" href="/documentation/assets/js/63.66946dde.js"><link rel="prefetch" href="/documentation/assets/js/64.d53bdeb7.js"><link rel="prefetch" href="/documentation/assets/js/65.0cd2da1f.js"><link rel="prefetch" href="/documentation/assets/js/66.03059dce.js"><link rel="prefetch" href="/documentation/assets/js/67.6f988923.js"><link rel="prefetch" href="/documentation/assets/js/68.303c1a05.js"><link rel="prefetch" href="/documentation/assets/js/69.3f4ed952.js"><link rel="prefetch" href="/documentation/assets/js/70.531d76be.js"><link rel="prefetch" href="/documentation/assets/js/71.ab3e74fc.js">
|
|
<link rel="stylesheet" href="/documentation/assets/css/styles.a8210063.css"><link rel="stylesheet" href="/documentation/assets/css/1.styles.77d89b12.css"><link rel="stylesheet" href="/documentation/assets/css/2.styles.08038ddb.css">
|
|
</head>
|
|
<body>
|
|
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/documentation/" class="home-link router-link-active"><!----> <span class="site-name">
|
|
Strapi Docs
|
|
</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"> <a href="https://github.com/strapi/strapi" target="_blank" rel="noopener noreferrer" class="repo-link">
|
|
GitHub
|
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar"><nav class="nav-links"> <a href="https://github.com/strapi/strapi" target="_blank" rel="noopener noreferrer" class="repo-link">
|
|
GitHub
|
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav> <div><select class="version-selector"><option value="/3.x.x/" selected="selected">Version 3.x.x</option><option value="/1.x.x/">Version 1.x.x</option></select></div> <ul class="sidebar-links"><li><div class="sidebar-group first"><p class="sidebar-heading"><span>UsefulLinks</span> <!----></p> <ul class="sidebar-group-items"><li><a href="/documentation/3.x.x/" class="sidebar-link">Introduction</a></li><li><a href="https://strapi.io" class="sidebar-link">Strapi Website</a></li><li><a href="https://github.com/strapi/strapi" class="sidebar-link">GitHub Repository</a></li><li><a href="https://github.com/strapi/strapi/blob/master/CONTRIBUTING.md" class="sidebar-link">Contribution Guide</a></li></ul></div></li><li><div class="sidebar-group"><p class="sidebar-heading"><span>Getting started</span> <!----></p> <ul class="sidebar-group-items"><li><a href="/documentation/3.x.x/getting-started/installation.html" class="sidebar-link">Installation</a></li><li><a href="/documentation/3.x.x/getting-started/quick-start.html" class="sidebar-link">Quick start</a></li></ul></div></li><li><div class="sidebar-group"><p class="sidebar-heading"><span>Globals</span> <!----></p> <ul class="sidebar-group-items"><li><a href="/documentation/3.x.x/api-reference/reference.html" class="sidebar-link">API Reference</a></li><li><a href="/documentation/3.x.x/cli/CLI.html" class="sidebar-link">Command Line Interface (CLI)</a></li><li><a href="/documentation/3.x.x/concepts/concepts.html" class="sidebar-link">Concepts</a></li><li><a href="/documentation/3.x.x/configurations/configurations.html" class="sidebar-link">Configurations</a></li></ul></div></li><li><div class="sidebar-group"><p class="sidebar-heading open"><span>Guides</span> <!----></p> <ul class="sidebar-group-items"><li><a href="/documentation/3.x.x/guides/authentication.html" class="sidebar-link">Authentication</a></li><li><a href="/documentation/3.x.x/guides/controllers.html" class="sidebar-link">Controllers</a></li><li><a href="/documentation/3.x.x/guides/deployment.html" class="sidebar-link">Deployment</a></li><li><a href="/documentation/3.x.x/guides/email.html" class="sidebar-link">Email</a></li><li><a href="/documentation/3.x.x/guides/filters.html" class="sidebar-link">Filters</a></li><li><a href="/documentation/3.x.x/guides/graphql.html" class="active sidebar-link">GraphQL</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/documentation/3.x.x/guides/graphql.html#usage" class="sidebar-link">Usage</a></li><li class="sidebar-sub-header"><a href="/documentation/3.x.x/guides/graphql.html#configurations" class="sidebar-link">Configurations</a></li><li class="sidebar-sub-header"><a href="/documentation/3.x.x/guides/graphql.html#shadow-crud" class="sidebar-link">Shadow CRUD</a></li><li class="sidebar-sub-header"><a href="/documentation/3.x.x/guides/graphql.html#aggregation-grouping" class="sidebar-link">Aggregation & Grouping</a></li><li class="sidebar-sub-header"><a href="/documentation/3.x.x/guides/graphql.html#customise-the-graphql-schema" class="sidebar-link">Customise the GraphQL schema</a></li><li class="sidebar-sub-header"><a href="/documentation/3.x.x/guides/graphql.html#faq" class="sidebar-link">FAQ</a></li></ul></li><li><a href="/documentation/3.x.x/guides/i18n.html" class="sidebar-link">Internationalization</a></li><li><a href="/documentation/3.x.x/guides/models.html" class="sidebar-link">Models</a></li><li><a href="/documentation/3.x.x/guides/policies.html" class="sidebar-link">Policies</a></li><li><a href="/documentation/3.x.x/guides/public-assets.html" class="sidebar-link">Public Assets</a></li><li><a href="/documentation/3.x.x/guides/requests.html" class="sidebar-link">Request</a></li></ul></div></li><li><div class="sidebar-group"><p class="sidebar-heading"><span>Advanced</span> <!----></p> <ul class="sidebar-group-items"><li><a href="/documentation/3.x.x/advanced/customize-admin.html" class="sidebar-link">Admin panel</a></li><li><a href="/documentation/3.x.x/advanced/hooks.html" class="sidebar-link">Hooks</a></li><li><a href="/documentation/3.x.x/advanced/logging.html" class="sidebar-link">Logging</a></li><li><a href="/documentation/3.x.x/advanced/middlewares.html" class="sidebar-link">Middlewares</a></li><li><a href="/documentation/3.x.x/advanced/usage-tracking.html" class="sidebar-link">Usage tracking</a></li></ul></div></li><li><div class="sidebar-group"><p class="sidebar-heading"><span>Help</span> <!----></p> <ul class="sidebar-group-items"><li><a href="https://github.com/strapi/strapi/wiki" class="sidebar-link">Migration guides</a></li><li><a href="/documentation/3.x.x/tutorials/" class="sidebar-link">Tutorials</a></li></ul></div></li></ul> </div> <div class="page"><div class="content"><h1 id="graphql"><a href="#graphql" aria-hidden="true" class="header-anchor">#</a> GraphQL</h1> <div class="warning custom-block"><p class="custom-block-title">WARNING</p> <p>This feature requires the GraphQL plugin (not installed by default).</p></div> <h2 id="usage"><a href="#usage" aria-hidden="true" class="header-anchor">#</a> Usage</h2> <p>To get started with GraphQL in your app, please install the plugin first. To do that, open your terminal and run the following command:</p> <div class="language- extra-class"><pre class="language-text"><code>strapi install graphql
|
|
</code></pre></div><p>Then, start your app and open your browser at <a href="http://localhost:1337/playground" target="_blank" rel="noopener noreferrer">http://localhost:1337/playground<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>. You should see the interface (GraphQL Playground) that will help you to write GraphQL query to explore your data.</p> <blockquote><p>Install the <a href="https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj/related" target="_blank" rel="noopener noreferrer">ModHeader<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> extension to set the <code>Authorization</code> header in your request</p></blockquote> <h2 id="configurations"><a href="#configurations" aria-hidden="true" class="header-anchor">#</a> Configurations</h2> <p>By default, the <a href="#shadow-crud">Shadow CRUD</a> feature is enabled and the GraphQL is set to <code>/graphql</code>. You can edit these configurations in the following files.</p> <p><strong>Path —</strong> <code>./plugins/graphql/config/settings.json</code>.</p> <div class="language- extra-class"><pre class="language-text"><code>{
|
|
"endpoint": "/graphql",
|
|
"shadowCRUD": true,
|
|
"depthLimit": 7
|
|
}
|
|
</code></pre></div><h3 id="query-api"><a href="#query-api" aria-hidden="true" class="header-anchor">#</a> Query API</h3> <p>In the section, we assume that the <a href="#shadow-crud">Shadow CRUD</a> feature is enabled. For each model, the plugin auto-generates queries which just fit to your needs.</p> <h5 id="fetch-a-single-entry"><a href="#fetch-a-single-entry" aria-hidden="true" class="header-anchor">#</a> Fetch a single entry</h5> <ul><li><code>id</code>: String</li></ul> <div class="language- extra-class"><pre class="language-text"><code>query {
|
|
user(id: "5aafe871ad624b7380d7a224") {
|
|
username
|
|
email
|
|
}
|
|
}
|
|
</code></pre></div><h5 id="fetch-multiple-entries"><a href="#fetch-multiple-entries" aria-hidden="true" class="header-anchor">#</a> Fetch multiple entries</h5> <div class="language- extra-class"><pre class="language-text"><code>query {
|
|
users {
|
|
username
|
|
email
|
|
}
|
|
}
|
|
</code></pre></div><p><strong>Filters</strong></p> <p>You can also apply different parameters to the query to make more complex queries.</p> <ul><li><code>limit</code> (integer): Define the number of returned entries.</li> <li><code>start</code> (integer): Define the amount of entries to skip.</li> <li><code>sort</code> (string): Define how the data should be sorted.</li> <li><code>where</code> (object): Define the filters to apply in the query.
|
|
<ul><li><code><field></code>: Equals.</li> <li><code><field>_ne</code>: Not equals.</li> <li><code><field>_lt</code>: Lower than.</li> <li><code><field>_lte</code>: Lower than or equal to.</li> <li><code><field>_gt</code>: Greater than.</li> <li><code><field>_gte</code>: Lower than or equal to.</li> <li><code><field>_contains</code>: Contains.</li> <li><code><field>_containss</code>: Contains sensitive.</li></ul></li></ul> <p>Return the second decade of users which have an email that contains <code>@strapi.io</code> ordered by username.</p> <div class="language- extra-class"><pre class="language-text"><code>query {
|
|
users(limit: 10, start: 10, sort: "username:asc", where: {
|
|
email_contains: "@strapi.io"
|
|
}) {
|
|
username
|
|
email
|
|
}
|
|
}
|
|
</code></pre></div><p>Return the users which have been created after the March, 19th 2018 4:21 pm.</p> <div class="language- extra-class"><pre class="language-text"><code>query {
|
|
users(where: {
|
|
createdAt_gt: "2018-03-19 16:21:07.161Z"
|
|
}) {
|
|
username
|
|
email
|
|
}
|
|
}
|
|
</code></pre></div><h2 id="shadow-crud"><a href="#shadow-crud" aria-hidden="true" class="header-anchor">#</a> Shadow CRUD</h2> <p>To simplify and automate the build of the GraphQL schema, we introduced the Shadow CRUD feature. It automatically generates the type definition, queries and resolvers based on your models. The feature also lets you make complex query with many arguments such as <code>limit</code>, <code>sort</code>, <code>start</code> and <code>where</code>.</p> <h4 id="example"><a href="#example" aria-hidden="true" class="header-anchor">#</a> Example</h4> <p>If you've generated an API called <code>Post</code> using the CLI <code>strapi generate:api post</code> or the administration panel, your model looks like this:</p> <p><strong>Path —</strong> <code>./api/post/models/Post.settings.json</code>.</p> <div class="language- extra-class"><pre class="language-text"><code>{
|
|
"connection": "default",
|
|
"options": {
|
|
"timestamps": true
|
|
},
|
|
"attributes": {
|
|
"title": {
|
|
"type": "string"
|
|
}
|
|
"content": {
|
|
"type": "text"
|
|
},
|
|
"published": {
|
|
"type": "boolean"
|
|
}
|
|
}
|
|
}
|
|
</code></pre></div><p>The generated GraphQL type and queries will be:</p> <div class="language- extra-class"><pre class="language-text"><code>type Post {
|
|
_id: String
|
|
created_at: String
|
|
updated_at: String
|
|
title: String
|
|
content: String
|
|
published: Boolean
|
|
}
|
|
|
|
type Query {
|
|
posts(sort: String, limit: Int, start: Int, where: JSON): [Post]
|
|
post(id: String!): Post
|
|
}
|
|
</code></pre></div><p>The query will use the generated controller's actions as resolvers. It means that the <code>posts</code> query will execute the <code>Post.find</code> action and the <code>post</code> query will use the <code>Post.findOne</code> action.</p> <h2 id="aggregation-grouping"><a href="#aggregation-grouping" aria-hidden="true" class="header-anchor">#</a> Aggregation & Grouping</h2> <blockquote><p>This feature is only available on Mongoose ORM.</p></blockquote> <p>Strapi now supports Aggregation & Grouping.
|
|
Let's consider again the model mentioned above:</p> <div class="language- extra-class"><pre class="language-text"><code>type Post {
|
|
_id: ID
|
|
createdAt: String
|
|
updatedAt: String
|
|
title: String
|
|
content: String
|
|
nb_likes: Int,
|
|
published: Boolean
|
|
}
|
|
|
|
</code></pre></div><p>Strapi will generate automatically for you the following queries & types:</p> <h3 id="aggregation"><a href="#aggregation" aria-hidden="true" class="header-anchor">#</a> Aggregation</h3> <div class="language- extra-class"><pre class="language-text"><code>type PostConnection {
|
|
values: [Post]
|
|
groupBy: PostGroupBy
|
|
aggregate: PostAggregator
|
|
}
|
|
|
|
type PostGroupBy {
|
|
_id: [PostConnection_id]
|
|
createdAt: [PostConnectionCreatedAt]
|
|
updatedAt: [PostConnectionUpdatedAt]
|
|
title: [PostConnectionTitle]
|
|
content: [PostConnectionContent]
|
|
nb_likes: [PostConnectionNbLikes],
|
|
published: [PostConnectionPublished]
|
|
}
|
|
|
|
type PostConnectionPublished {
|
|
key: Boolean
|
|
connection: PostConnection
|
|
}
|
|
|
|
type PostAggregator {
|
|
count: Int
|
|
sum: PostAggregatorSum
|
|
avg: PostAggregatorAvg
|
|
min: PostAggregatorMin
|
|
max: PostAggregatorMax
|
|
}
|
|
|
|
type PostAggregatorAvg {
|
|
nb_likes: Float
|
|
}
|
|
|
|
type PostAggregatorMin { // Same for max and sum
|
|
nb_likes: Int
|
|
}
|
|
|
|
type Query {
|
|
postsConnection(sort: String, limit: Int, start: Int, where: JSON): PostConnection
|
|
}
|
|
</code></pre></div><p>Getting the total count and the average likes of posts:</p> <div class="language- extra-class"><pre class="language-text"><code>postsConnection {
|
|
aggregate {
|
|
count
|
|
avg {
|
|
nb_likes
|
|
}
|
|
}
|
|
|
|
}
|
|
</code></pre></div><p>Let's say we want to do the same query but for only published posts</p> <div class="language- extra-class"><pre class="language-text"><code>postsConnection(where: { published: true }) {
|
|
aggregate {
|
|
count
|
|
avg {
|
|
nb_likes
|
|
}
|
|
}
|
|
|
|
}
|
|
</code></pre></div><p>Gettings the average likes of published and unpublished posts</p> <div class="language- extra-class"><pre class="language-text"><code>postsConnection {
|
|
groupBy {
|
|
published: {
|
|
key
|
|
connection {
|
|
aggregate {
|
|
avg {
|
|
nb_likes
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</code></pre></div><p>Result</p> <div class="language-JSON extra-class"><pre class="language-json"><code><span class="token punctuation">{</span>
|
|
data<span class="token operator">:</span> <span class="token punctuation">{</span>
|
|
postsConnection<span class="token operator">:</span> <span class="token punctuation">{</span>
|
|
groupBy<span class="token operator">:</span> <span class="token punctuation">{</span>
|
|
published<span class="token operator">:</span> <span class="token punctuation">[</span>
|
|
<span class="token punctuation">{</span>
|
|
key<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
|
|
connection<span class="token operator">:</span> <span class="token punctuation">{</span>
|
|
aggregate<span class="token operator">:</span> <span class="token punctuation">{</span>
|
|
avg <span class="token punctuation">{</span>
|
|
nb_likes<span class="token operator">:</span> <span class="token number">10</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
|
<span class="token punctuation">{</span>
|
|
key<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
|
|
connection<span class="token operator">:</span> <span class="token punctuation">{</span>
|
|
aggregate<span class="token operator">:</span> <span class="token punctuation">{</span>
|
|
avg <span class="token punctuation">{</span>
|
|
nb_likes<span class="token operator">:</span> <span class="token number">0</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">]</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
</code></pre></div><h2 id="customise-the-graphql-schema"><a href="#customise-the-graphql-schema" aria-hidden="true" class="header-anchor">#</a> Customise the GraphQL schema</h2> <p>If you want to define a new scalar, input or enum types, this section is for you. To do so, you will have to create a <code>schema.graphql</code> file. This file has to be placed into the config folder of each API <code>./api/*/config/schema.graphql</code> or plugin <code>./plugins/*/config/schema.graphql</code>.</p> <p><strong>Structure —</strong> <code>schema.graphql</code>.</p> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
|
|
definition<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">``</span></span><span class="token punctuation">,</span>
|
|
query<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">``</span></span><span class="token punctuation">,</span>
|
|
type<span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
Query<span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
|
</code></pre></div><ul><li><code>definition</code> (string): let's you define new type, input, etc.</li> <li><code>query</code> (string): where you add custom query.</li> <li><code>type</code> (object): allows you to add description, deprecated field or disable the <a href="#shadow-crud">Shadow CRUD</a> feature on a specific type.</li> <li><code>resolver</code> (object):
|
|
<ul><li><code>Query</code> (object): let's you define custom resolver, policies for a query.</li></ul></li></ul> <h4 id="example-2"><a href="#example-2" aria-hidden="true" class="header-anchor">#</a> Example</h4> <p>Let say we are using the same previous <code>Post</code> model.</p> <p><strong>Path —</strong> <code>./api/post/config/schema.graphql</code>.</p> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
|
|
definition<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`
|
|
enum PostStatusInput {
|
|
draft
|
|
reviewing
|
|
reviewed
|
|
published
|
|
deleted
|
|
}
|
|
`</span></span><span class="token punctuation">,</span>
|
|
query<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`
|
|
postsByAuthor(id: String, status: PostStatusInput, limit: Int): [Post]!
|
|
`</span></span><span class="token punctuation">,</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
Query<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
post<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
description<span class="token punctuation">:</span> <span class="token string">'Return a single post'</span><span class="token punctuation">,</span>
|
|
policy<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">'plugins.users-permissions.isAuthenticated'</span><span class="token punctuation">,</span> <span class="token string">'isOwner'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token comment">// Apply the 'isAuthenticated' policy of the `Users & Permissions` plugin, then the 'isOwner' policy before executing the resolver.</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
|
posts<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
description<span class="token punctuation">:</span> <span class="token string">'Return a list of posts'</span><span class="token punctuation">,</span> <span class="token comment">// Add a description to the query.</span>
|
|
deprecated<span class="token punctuation">:</span> <span class="token string">'This query should not be used anymore. Please consider using postsByAuthor instead.'</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
|
postsByAuthor<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
description<span class="token punctuation">:</span> <span class="token string">'Return the posts published by the author'</span><span class="token punctuation">,</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token string">'Post.findByAuthor'</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
|
postsByTags<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
description<span class="token punctuation">:</span> <span class="token string">'Return the posts published by the author'</span><span class="token punctuation">,</span>
|
|
resolverOf<span class="token punctuation">:</span> <span class="token string">'Post.findByTags'</span><span class="token punctuation">,</span> <span class="token comment">// Will apply the same policy on the custom resolver than the controller's action `findByTags`.</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> options<span class="token punctuation">,</span> ctx<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
|
|
<span class="token comment">// ctx is the context of the Koa request.</span>
|
|
<span class="token keyword">await</span> strapi<span class="token punctuation">.</span>controllers<span class="token punctuation">.</span>posts<span class="token punctuation">.</span><span class="token function">findByTags</span><span class="token punctuation">(</span>ctx<span class="token punctuation">)</span><span class="token punctuation">;</span>
|
|
|
|
<span class="token keyword">return</span> ctx<span class="token punctuation">.</span>body<span class="token punctuation">.</span>posts <span class="token operator">||</span> <span class="token template-string"><span class="token string">`There is no post.`</span></span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
|
</code></pre></div><h3 id="define-a-new-type"><a href="#define-a-new-type" aria-hidden="true" class="header-anchor">#</a> Define a new type</h3> <p>Edit the <code>definition</code> attribute in one of the <code>schema.graphql</code> files of your project by using the GraphQL Type language string.</p> <div class="note custom-block"><p>The easiest way is to create a new model using the CLI <code>strapi generate:model category --api post</code>, so you don't need to customise anything.</p></div> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
|
|
definition<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`
|
|
type Person {
|
|
id: Int!
|
|
firstname: String!
|
|
lastname: String!
|
|
age: Int
|
|
children: [Person]
|
|
}
|
|
`</span></span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
|
</code></pre></div><p>To explore the data of the new type <code>Person</code>, you need to define a query and associate a resolver to this query.</p> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
|
|
definition<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`
|
|
type Person {
|
|
id: Int!
|
|
firstname: String!
|
|
lastname: String!
|
|
age: Int
|
|
children: [Person]
|
|
}
|
|
`</span></span><span class="token punctuation">,</span>
|
|
query<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`
|
|
person(id: Int!): Person
|
|
`</span></span><span class="token punctuation">,</span>
|
|
type<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
Person<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
_description<span class="token punctuation">:</span> <span class="token string">'The Person type description'</span><span class="token punctuation">,</span> <span class="token comment">// Set the description for the type itself.</span>
|
|
firstname<span class="token punctuation">:</span> <span class="token string">'The firstname of the person'</span><span class="token punctuation">,</span>
|
|
lastname<span class="token punctuation">:</span> <span class="token string">'The lastname of the person'</span><span class="token punctuation">,</span>
|
|
age<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
description<span class="token punctuation">:</span> <span class="token string">'The age of the person'</span><span class="token punctuation">,</span>
|
|
deprecated<span class="token punctuation">:</span> <span class="token string">'We are not using the age anymore, we can find it thanks to our powerful AI'</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">,</span>
|
|
children<span class="token punctuation">:</span> <span class="token string">'The children of the person'</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
Query<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
person<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
description<span class="token punctuation">:</span> <span class="token string">'Return a single person'</span><span class="token punctuation">,</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token string">'Person.findOne'</span> <span class="token comment">// It will use the action `findOne` located in the `Person.js` controller*.</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
|
</code></pre></div><blockquote><p>The resolver parameter also accepts an object as a value to target a controller located in a plugin.</p></blockquote> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
|
|
<span class="token operator">...</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
Query<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
person<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
description<span class="token punctuation">:</span> <span class="token string">'Return a single person'</span><span class="token punctuation">,</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
plugin<span class="token punctuation">:</span> <span class="token string">'users-permissions'</span><span class="token punctuation">,</span>
|
|
handler<span class="token punctuation">:</span> <span class="token string">'User.findOne'</span> <span class="token comment">// It will use the action `findOne` located in the `Person.js` controller inside the plugin `Users & Permissions`.</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
|
</code></pre></div><h3 id="add-description-and-deprecated-reason"><a href="#add-description-and-deprecated-reason" aria-hidden="true" class="header-anchor">#</a> Add description and deprecated reason</h3> <p>One of the most powerful features of GraphQL is the auto-documentation of the schema. The GraphQL plugin allows you to add a description to a type, a field and a query. You can also deprecate a field or a query.</p> <p><strong>Path —</strong> <code>./api/post/models/Post.settings.json</code>.</p> <div class="language- extra-class"><pre class="language-text"><code>{
|
|
"connection": "default",
|
|
"info": {
|
|
"description": "The Post type description"
|
|
},
|
|
"options": {
|
|
"timestamps": true
|
|
},
|
|
"attributes": {
|
|
"title": {
|
|
"type": "string",
|
|
"description": "The title of the post",
|
|
"deprecated": "We are not using the title anymore, it is auto-generated thanks to our powerful AI"
|
|
},
|
|
"content": {
|
|
"type": "text",
|
|
"description": "The content of the post."
|
|
},
|
|
"published": {
|
|
"type": "boolean",
|
|
"description": "Is the post published or not. Yes = true."
|
|
}
|
|
}
|
|
}
|
|
</code></pre></div><p>It might happens that you want to add a description to a query or deprecate it. To do that, you need to use the <code>schema.graphql</code> file.</p> <blockquote><p>Remember: The <code>schema.graphql</code> file has to be placed into the config folder of each API <code>./api/*/config/schema.graphql</code> or plugin <code>./plugins/*/config/schema.graphql</code>.</p></blockquote> <p><strong>Path —</strong> <code>./api/post/config/schema.graphql</code>.</p> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
Query<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
posts<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
description<span class="token punctuation">:</span> <span class="token string">'Return a list of posts'</span><span class="token punctuation">,</span> <span class="token comment">// Add a description to the query.</span>
|
|
deprecated<span class="token punctuation">:</span> <span class="token string">'This query should not be used anymore. Please consider using postsByAuthor instead.'</span> <span class="token comment">// Deprecate the query and explain the reason why.</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
|
</code></pre></div><h3 id="execute-a-policy-before-a-resolver"><a href="#execute-a-policy-before-a-resolver" aria-hidden="true" class="header-anchor">#</a> Execute a policy before a resolver</h3> <p>Sometimes a query needs to be only accessible to authenticated user. To handle this, Strapi provides a solid policy system. A policy is a function executed before the final action (the resolver). You can define an array of policy that will be executed in order.</p> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
Query<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
posts<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
description<span class="token punctuation">:</span> <span class="token string">'Return a list of posts'</span><span class="token punctuation">,</span>
|
|
policy<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">'plugins.users-permissions.isAuthenticated'</span><span class="token punctuation">,</span> <span class="token string">'isOwner'</span><span class="token punctuation">,</span> <span class="token string">'global.logging'</span><span class="token punctuation">]</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
|
</code></pre></div><p>In this example, the policy <code>isAuthenticated</code> located in <code>./plugins/users-permissions/config/policies/isAuthenticated.js</code> will be executed first. Then, the <code>isOwner</code> policy located in the <code>Post</code> API <code>./api/post/config/policies/isOwner.js</code>. Next, it will execute the <code>logging</code> policy located in <code>./config/policies/logging.js</code>. Finally, the resolver will be executed.</p> <div class="note custom-block"><p>There is no custom resolver in that case, so it will execute the default resolver (Post.find) provided by the Shadow CRUD feature.</p></div> <h3 id="link-a-query-to-a-controller-action"><a href="#link-a-query-to-a-controller-action" aria-hidden="true" class="header-anchor">#</a> Link a query to a controller action</h3> <p>By default, the plugin will execute the actions located in the controllers that has been generated via the Content-Type Builder plugin or the CLI. For example, the query <code>posts</code> is going to execute the logic inside the <code>find</code> action in the <code>Post.js</code> controller. It might happens that you want to execute another action or a custom logic for one of your query.</p> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
Query<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
posts<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
description<span class="token punctuation">:</span> <span class="token string">'Return a list of posts by author'</span><span class="token punctuation">,</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token string">'Post.findByAuthor'</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
|
</code></pre></div><p>In this example, it will execute the <code>findByAuthor</code> action of the <code>Post</code> controller. It also means that the resolver will apply on the <code>posts</code> query the permissions defined on the <code>findByAuthor</code> action (through the administration panel).</p> <div class="note custom-block"><p>The <code>obj</code> parameter is available via <code>ctx.params</code> and the <code>options</code> are available via <code>ctx.query</code> in the controller's action.</p></div> <h3 id="define-a-custom-resolver"><a href="#define-a-custom-resolver" aria-hidden="true" class="header-anchor">#</a> Define a custom resolver</h3> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
Query<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
posts<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
description<span class="token punctuation">:</span> <span class="token string">'Return a list of posts by author'</span><span class="token punctuation">,</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> options<span class="token punctuation">,</span> context<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
|
|
<span class="token comment">// You can return a raw JSON object or a promise.</span>
|
|
|
|
<span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token punctuation">{</span>
|
|
title<span class="token punctuation">:</span> <span class="token string">'My first blog post'</span><span class="token punctuation">,</span>
|
|
content<span class="token punctuation">:</span> <span class="token string">'Whatever you want...'</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
|
</code></pre></div><p>You can also execute a custom logic like above. However, the roles and permissions layers won't work.</p> <h3 id="apply-permissions-on-a-query"><a href="#apply-permissions-on-a-query" aria-hidden="true" class="header-anchor">#</a> Apply permissions on a query</h3> <p>It might happens that you want apply our permissions layer on a query. That's why, we created the <code>resolverOf</code> attribute. This attribute defines which are the permissions that should be applied to this resolver. By targeting an action it means that you're able to edit permissions for this resolver directly from the administration panel.</p> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
Query<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
posts<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
description<span class="token punctuation">:</span> <span class="token string">'Return a list of posts by author'</span><span class="token punctuation">,</span>
|
|
resolverOf<span class="token punctuation">:</span> <span class="token string">'Post.find'</span><span class="token punctuation">,</span> <span class="token comment">// Will apply the same policy on the custom resolver than the controller's action `find` located in `Post.js`.</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> options<span class="token punctuation">,</span> context<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
|
|
<span class="token comment">// You can return a raw JSON object or a promise.</span>
|
|
|
|
<span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token punctuation">{</span>
|
|
title<span class="token punctuation">:</span> <span class="token string">'My first blog post'</span><span class="token punctuation">,</span>
|
|
content<span class="token punctuation">:</span> <span class="token string">'Whatever you want...'</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
|
</code></pre></div><h3 id="disable-a-query-or-a-type"><a href="#disable-a-query-or-a-type" aria-hidden="true" class="header-anchor">#</a> Disable a query or a type</h3> <p>To do that, we need to use the <code>schema.graphql</code> like below:</p> <div class="language-js extra-class"><pre class="language-js"><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
|
|
type<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
Post<span class="token punctuation">:</span> <span class="token boolean">false</span> <span class="token comment">// The Post type won't be "queriable".</span>
|
|
<span class="token punctuation">}</span>
|
|
resolver<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
Query<span class="token punctuation">:</span> <span class="token punctuation">{</span>
|
|
posts<span class="token punctuation">:</span> <span class="token boolean">false</span> <span class="token comment">// The `posts` query will no longer be in the GraphQL schema.</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span>
|
|
<span class="token punctuation">}</span><span class="token punctuation">;</span>
|
|
</code></pre></div><h2 id="faq"><a href="#faq" aria-hidden="true" class="header-anchor">#</a> FAQ</h2> <p><strong>How are the types name defined?</strong></p> <p>The type name is the global ID of the model. You can find the global ID of a model like that <code>strapi.models[xxx].globalId</code> or <code>strapi.plugins[xxx].models[yyy].globalId</code>.</p> <p><strong>Where should I put the field description and deprecated reason?</strong></p> <p>We recommend to put the field description and deprecated reason in the model. Right now, the GraphQL plugin is the only which uses these fields. Another plugin could use this description in the future as well. However, sometimes you don't have the choice, especially when you're defining a custom type.</p> <div class="note custom-block"><p>It's not a bad practice to put the description and deprecated attribute in the <code>schema.graphql</code>, though.</p></div> <p><strong>Why are the "createdAt" and "updatedAt" field added to my type?</strong></p> <p>The plugin detects if the <code>timestamps</code> option is set to <code>true</code> in the model. By default, when you generate an API this option is checked. Set it to <code>false</code> in your model to remove these fields.</p></div> <div class="page-edit"><div class="edit-link"><a href="https://github.com/strapi/strapi/edit/master/docs/3.x.x/guides/graphql.md" target="_blank" rel="noopener noreferrer">Improve this page</a> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></div> <!----></div> <div class="page-nav"><p class="inner"><span class="prev">
|
|
← <a href="/documentation/3.x.x/guides/filters.html" class="prev">
|
|
Filters
|
|
</a></span> <span class="next"><a href="/documentation/3.x.x/guides/i18n.html">
|
|
Internationalization
|
|
</a> →
|
|
</span></p></div> </div></div></div>
|
|
<script src="/documentation/assets/js/45.6746c3dc.js" defer></script><script src="/documentation/assets/js/app.a8210063.js" defer></script>
|
|
</body>
|
|
</html>
|