How to simplify graphql response - graphql

For example my graphql's query is:
products {
name,
price,
brand {
name
}
}
Which produces this response:
{
"data": {
"products": [
{
"name": "Black Dress",
"price": 520,
"brand": {
"name": "Coach"
}
}
]
}
}
Can this
"brand": {
"name": "Coach"
}
be simplified to this somehow?
"brandName": "Coach"

Currently, without any additional dependencies and if you don't want to update schema, you cannot control the shape of the object returned by GraphQL if you like to control the shape that can be possible by graphql-leveler.
The graphql-leveler will provide a method call _get through which you can manage the shape of your object you can do simply:
{
brandName: _get(products: 'brand.name')
}
Note: to use graphql-leveler, simply add graphql-leveler to your dependencies, require LevelerObjectType, and use it instead of GraphQLObjectType. Done!

Related

Incorrectly selected data in the query

Only articles that contain the EmailMarketing tag are needed.
I'm probably doing the wrong search on the tag, since it's an array of values, not a single object, but I don't know how to do it right, I'm just learning graphql. Any help would be appreciated
query:
query {
enArticles {
title
previewText
tags(where: {name: "EmailMarketing"}){
name
}
}
}
result:
{
"data": {
"enArticles": [
{
"title": "title1",
"previewText": "previewText1",
"tags": [
{
"name": "EmailMarketing"
},
{
"name": "Personalization"
},
{
"name": "Advertising_campaign"
}
]
},
{
"title": "title2",
"previewText": "previewText2",
"tags": [
{
"name": "Marketing_strategy"
},
{
"name": "Marketing"
},
{
"name": "Marketing_campaign"
}
]
},
{
"title": "article 12",
"previewText": "article12",
"tags": []
}
]
}
}
I believe you first need to have coded an equality operator within your GraphQL schema. There's a good explanation of that here.
Once you add an equality operator - say, for example _eq - you can use it something like this:
query {
enArticles {
title
previewText
tags(where: {name: {_eq: "EmailMarketing"}}){
name
}
}
}
Specifically, you would need to create a filter and resolver.
The example here may help.

GraphQL filtering an array

I am using GatsBy GraphiQL to write a query to return a single element, but the query returns all of the elements.
Here is my testing data:
{
"data": {
"mKT": {
"data": [
{
"name": "Apple",
"description": "apple's desc"
},
{
"name": "Orange",
"description": "orange's desc"
},
{
"name": "Banana",
"description": "banana's desc"
}
]
}
},
"extensions": {}
}
And, here is the GraphQL query:
query MyQuery {
mKT(data: {elemMatch: {name: {eq: "Apple"}}}) {
data {
name
description
}
}
}
I expect to get:
{
"name": "Apple",
"description": "apple's desc"
}
However, running the query returns all of the data.
Any idea how to fix this issue?
Simply use:
query MyQuery {
mKT(data: {filter: {name: {eq: "Apple"}}}) {
data {
name
description
}
}
}
The filter keyword should do the trick.
Check the GraphQL Reference (in Gatsby docs) for further details.
I believe this is the same case as:
GraphQL query to access first item in an array?
You cannot use filters, limits, etc to an structure if it have not been defined on the source.
If you have access to the source, add something like limit to the field data.
If not, you will get the full array, and you have to process it on your side.

GraphQL - How to get field types from the retrieved schema?

Knowing the schema (fetched via getIntrospectionQuery), how could I get the type of a particular field?
For example, say I run this query:
query {
User {
name
lastUpdated
friends {
name
}
}
}
and get this result:
{
"data": {
"User": [
{
"name": "alice",
"lastUpdated": "2018-02-03T17:22:49+00:00",
"friends": []
},
{
"name": "bob",
"lastUpdated": "2017-09-01T17:08:49+00:00",
"friends": [
{
"name": "eve"
}
]
}
]
}
}
I'd like to know the types of the fields and construct something like this:
{
"name": "String",
"lastUpdated": "timestamptz",
"friends": "[Friend]"
}
How could I do that without extra requests to the server?
After retrieving the schema, you can build it into a JSON object (if your graphql framework does not do it already for you).
Using a JSON parser, you can retrieve the the types of each field.
I will not enter into the detail, as it would depend on the technology your are using.

Is it possible to get rid of the 'data' ,'nodes', ... fields?

I have the following GraphQL query:
{
allForums {
nodes {
name,
topics: topicsByForumId(orderBy: [TITLE_ASC]) {
nodes {
title
}
}
}
}
}
This returns something as following:
{
"data": {
"allForums": {
"nodes": [
{
"name": "1",
"topics": {
"nodes": [
{
"title": "a"
},
{
"title": "b"
}
]
}
}
]
}
}
}
I would like to get the result below:
[
{
"name": "1",
"topics": [
{
"title": "a"
},
{
"title", "b"
}
]
}
]
Is it possible to get rid of the data, nodes, ... fields? Is that something that can be done within GraphQL, or should I do that in my service implementation?
I am using PostGraphile v4.2.0 as a GraphQL implementation, on top of PostgreSQL v11.
As indicated in the docs, you can expose a simpler interface for connections, or eliminate the default Relay-based connection interface altogether:
If you prefer a simpler list interface over GraphQL connections then you can enable that either along-side our connections (both) or exclusively (only) using our --simple-collections [omit|both|only] option.

How to filter GraphQL results by a descendent without edges?

I just started looking at GraphQL and I am wondering if there is a way to filter results that don't have any nodes. Here is a relatively simple example query:
query {
organization(login:"GitHub") {
repositories(first: 20) {
edges {
node {
name
pullRequests(first: 5, states: OPEN){
edges {
node {
title
author{
login
}
updatedAt
}
}
}
}
}
}
}
}
and here is a subset of the results that query returns:
{
"data": {
"organization": {
"repositories": {
"edges": [
{
"node": {
"name": "gitignore",
"pullRequests": {
"edges": [
{
"node": {
"title": "Create new CodeComposerStudio.gitignore",
"author": {
"login": "wolf99"
},
"updatedAt": "2017-07-26T20:31:53Z"
}
},
{
"node": {
"title": "Create PVS.gitignore",
"author": {
"login": "cesaramh"
},
"updatedAt": "2017-05-01T19:42:07Z"
}
},
{
"node": {
"title": "gitignore for Magic Software Enterprises product xpa ",
"author": {
"login": "tommes"
},
"updatedAt": "2017-05-01T19:41:53Z"
}
},
{
"node": {
"title": "Create PSoC.gitignore",
"author": {
"login": "dbrwn"
},
"updatedAt": "2017-05-01T19:41:39Z"
}
},
{
"node": {
"title": "add ThinkPHP gitignore file",
"author": {
"login": "swumao"
},
"updatedAt": "2017-05-01T19:40:53Z"
}
}
]
}
}
},
{
"node": {
"name": "dmca",
"pullRequests": {
"edges": []
}
}
}
]
}
}
}
}
So I'd like to know if there is a way to modify my query so that it would not return the node named dmca since there are no edges on pullRequests.
If you are using githubs graphql api than it seems that there is no way to filter those edges,
But if you're implementing the graphql server then it's possible to know what the edges nodes are and thus filter it in the edge resolver
According to GitHub repositories documentation does not allow that kind of filtering.
first: Int
Returns the first n elements from the list.
after: String
Returns the elements in the list that come after the specified cursor.
last: Int
Returns the last n elements from the list.
before: String
Returns the elements in the list that come before the specified cursor.
privacy: RepositoryPrivacy
If non-null, filters repositories according to privacy
orderBy: RepositoryOrder
Ordering options for repositories returned from the connection
affiliations: [RepositoryAffiliation]
Affiliation options for repositories returned from the connection
isLocked: Boolean
If non-null, filters repositories according to whether they have been locked
isFork: Boolean
If non-null, filters repositories according to whether they are forks of another repository
So I don't think that can be done.

Resources