docs/1.8/04-Reference/03-Prisma-API/03-Queries.md
The Prisma API offers two kinds of queries:
When working with the Prisma API, the following features are also useful to keep in mind:
In general, the Prisma API of a service is generated based on its data model. To explore the operations in your Prisma API, you can use a GraphQL Playground.
In the following, we will explore example queries based on a Prisma service with this data model:
type Post {
id: ID! @unique
title: String!
published: Boolean!
author: User!
}
type User {
id: ID! @unique
age: Int
email: String! @unique
name: String!
accessRole: AccessRole
posts: [Post!]!
}
enum AccessRole {
USER
ADMIN
}
We can use object queries to fetch either a single node, or a list of nodes for a certain object type.
Here, we use the posts query to fetch a list of Post nodes. In the response, we include only the id and title of each Post node:
query {
posts {
id
title
}
}
We can also query a specific Post node using the post query. Note that we're using the where argument to select the node:
query {
post(where: {
id: "cixnen24p33lo0143bexvr52n"
}) {
id
title
published
}
}
Because User is another type in our data model, users is another available query. Again, we can use the where argument to specify conditions for the returned users. In this example, we filter for all User nodes that have their age higher than 18:
query {
users(where: {
age_gt: 18
}) {
id
name
}
}
This also works across relations, here we're fetching those Post nodes that have an author with the age higher than 18:
query {
posts(where: {
author: {
age_gt: 18
}
}) {
id
title
author {
name
age
}
}
}
You can read more about node selection here.
Object queries directly return a list of nodes. In special cases, or when using advanced features, using connection queries is the preferred option. They are an extension of (and fully compliant with) Relay connections. The core idea of Relay connections is to provide meta-information about the edges in the data graph. For example, each edge not only has access to information about the corresponding object (the node) but also is associated with a cursor that allows to implement powerful pagination.
Here, we fetch all Post nodes using the postsConnection query. Notice that we're also asking for the cursor of each edge:
# Fetch all posts
query {
postsConnection {
edges {
cursor
node {
id
title
}
}
}
}
Connection queries also expose aggregation features via aggregate:
# Count all posts with a title containing 'GraphQL'
query {
postsConnection(where: {
title_contains: "GraphQL"
}) {
aggregate {
count
}
}
}
Note that more aggregations will be added over time. Find more information about the roadmap here.
Every available relation in your data model adds a new field to the queries of the two models it connects.
Here, we are fetching a specific User, and all her related Post nodes using the posts field:
query {
user(where: {
id: "cixnekqnu2ify0134ekw4pox8"
}) {
id
name
posts {
id
published
}
}
}
user.posts acts exactly like the top-level posts query in that it lets you specify which fields of the Post type you're interested in.
Throughout the Prisma API, you'll find query arguments that you can provide to further control the query response. It can be either of the following:
orderBywherefirst and before, last and after, and skipThese query arguments can be combined to achieve very specific query responses.
When querying all nodes of a type you can supply the orderBy argument for every scalar field of the type: orderBy: <field>_ASC or orderBy: <field>_DESC.
Order the list of all Post nodes ascending by title:
query {
posts(orderBy: title_ASC) {
id
title
published
}
}
Order the list of all Post nodes descending by published:
query {
posts(orderBy: published_DESC) {
id
title
published
}
}
Note: The field you are ordering by does not have to be selected in the actual query. If you do not specify an ordering, the response is automatically ordered ascending by the
idfield.
It's currently not possible to order responses by multiple fields or by related fields. Join the discussion in the feature requests if you're interested in these features!
When querying all nodes of a type you can supply different parameters to the where argument to constrain the data in the response according to your requirements. The available options depend on the scalar and relational fields defined on the type in question.
If you supply exactly one parameter to the where argument, the query response will only contain nodes that adhere to this constraint. Multiple filters can be combined using AND and/or OR, see below for more.
The easiest way to filter a query response is by supplying a field value to filter by.
Query all Post nodes that are not yet published:
query {
posts(where: {
published: false
}) {
id
title
published
}
}
Depending on the type of the field you want to filter by, you have access to different advanced criteria you can use to filter your query response. See how to explore available filter criteria.
Query all Post nodes whose title is in a given list of strings:
query {
posts(where: {
title_in: ["My biggest Adventure", "My latest Hobbies"]
}) {
id
title
published
}
}
Note: you have to supply a list as the
<field>_inargument:title_in: ["My biggest Adventure", "My latest Hobbies"].
For to-one relations, you can define conditions on the related node by nesting the according argument in where.
Query all Post nodes where the author has the USER access role:
query {
posts(where: {
author: {
accessRole: USER
}
}) {
title
}
}
For to-many relations, three additional arguments are available: every, some and none, to define that a condition should match every, some or none related nodes.
Query all User nodes that have at least one Post node that's published:
query {
users(where: {
posts_some: {
published: true
}
}) {
id
posts {
published
}
}
}
Relation filters are also available in the nested arguments for to-one or to-many relations.
Query all User nodes that did not like a Post of an author in the ADMIN access role:
query {
users(where: {
likedPosts_none: {
author: {
accessRole: ADMIN
}
}
}) {
name
}
}
Note:
likedPostsis not part of the above mentioned data model but can easily be added by adding the corresponding field to theUsertype:likedPosts: [Post!]! @relation(name: "LikedPosts"). Note that we also provide anamefor the relation to resolve the ambiguity we would otherwise create because there are two relation fields targettingPoston theUsertype.
You can use the filter combinators OR, AND, NOT to create an arbitrary logical combination of filter conditions.
For AND all of the nested conditions have to be true. For OR one of the nested conditions have to be true. For NOT all of the nested conditions have to be false since they are combined by and internally.
OR, AND and NOTLet's start with an easy example:
Query all Post nodes that are published and whose title is in a given list of strings:
query {
posts(where: {
AND: [{
title_in: ["My biggest Adventure", "My latest Hobbies"]
}, {
published: true
}]
}) {
id
title
published
}
}
Note:
OR,ANDandNOTand accept a list as input where each list item is an object and therefore needs to be wrapped with{}, for example:AND: [{title_in: ["My biggest Adventure", "My latest Hobbies"]}, {published: true}]
AND, OR and NOTYou can combine and even nest the filter combinators AND, OR and NOT to create arbitrary logical combinations of filter conditions.
Query all Post nodes that are either published and whose title is in a list of given strings, or have the specific id we supply:
query($published: Boolean) {
posts(where: {
OR: [{
AND: [{
title_in: ["My biggest Adventure", "My latest Hobbies"]
}, {
published: $published
}]
}, {
id: "cixnen24p33lo0143bexvr52n"
}]
}) {
id
title
published
}
}
Notice how we nested the
ANDcombinator inside theORcombinator, on the same level with theidvalue filter.
Apart from the filter combinators AND, OR and NOT, the available filter arguments for a query for all nodes of a type depend on the fields of the type and their types.
Use the GraphQL Playground to explore available filter conditions.
Currently, neither scalar list filters nor JSON filters are available. Join the discussion in the respective feature requests on GitHub.
When querying all nodes of a specific object type, you can supply arguments that allow you to paginate the query response.
Pagination allows you to request a certain amount of nodes at the same time. You can seek forwards or backwards through the nodes and supply an optional starting node:
first; specify a starting node with after.last; specify a starting node with before.You can also skip an arbitrary amount of nodes in whichever direction you are seeking by supplying the skip argument.
Consider a blog where only 3 Post nodes are shown at the front page. To query the first page:
query {
posts(first: 3) {
id
title
}
}
To query the first two Post nodes after the first Post node:
query {
posts(
first: 2
after: "cixnen24p33lo0143bexvr52n"
) {
id
title
}
}
We could reach the same result by combining first and skip:
query {
posts(
first: 2
skip: 1
) {
id
title
}
}
Query the last 2 posts:
query {
posts(last: 2) {
id
title
}
}
Note: You cannot combine
firstwithbeforeorlastwithafter. You can also query for more nodes than exist without an error message.
Note that by default, Prisma returns a maximum of 1000 nodes. This can be overridden by setting the pagination parameters accordingly. If you do not set any pagination parameters, Prisma will set a limit of 1000.