How to graphql after a certain date in contentful? - graphql

I'm using Contentful's GraphQL API. What I want to do is to query all the events that haven't past yet.
I tried using lt, but that doesn't seem to be working. I also found out that the date is a string, so what options do I have?
eventCollection(where: {eventEndDate: {lt: "2022-10-27T00:00:00.000-06:00"}}){
items {
slug
eventEndDate
}
}
A normal query (without the where condition) gives you:
"eventCollection": {
"items": [
{
"slug": "black-friday",
"eventEndDate": "2022-11-27T12:00:00.000-07:00"
}
]
}

You should have an eventEndDate_gte filter available. On every field, there will be type dependent filter available. It's best to use GraphiQL or the GraphQL Playground to discover available filter options.
The following filter works fine for my space.
query {
tilPostCollection(where: {date_gte: "2022-09-05T00:00:00.000+02:00"}) {
items {
title
date
}
}
}

Related

Is there any way to perform GROUP BY operation in GraphQL?

I need to group data in a table by using a particular field in the table. And couldn't find GROUP BY feature in GraphQL. Is there any way to achieve that ?
Current Format :
[
{
"my_state":"karnatak",
"from_state":"kerala",
"route":"wayanad"
},
{
"my_state":"karnatak",
"from_state":"kerala",
"route":"Mangalore"
},
{
"my_state":"karnatak",
"from_state":"kerala",
"route":"Palakkad"
},
{
"my_state":"karnatak",
"from_state":"tamilnadu",
"route":"hosure"
},
{
"my_state":"karnatak",
"from_state":"tamilnadu",
"route":"selam"
},
{
"my_state":"karnatak",
"from_state":"tamilnadu",
"route":"chennai"
}
]
Required Format:
from_state: "karnatak",
route: [
{
route: "chennai"
},
{
route: "selam"
    },
    ............
  ]
GraphQL is a query language for APIs and it does not really "contain features" like GroupBy, Count, Sort, etc. Those features or queries have to be implemented in the server (GraphQL API) and it leaves you a couple of options:
If you own the API(server) then you would have to create your own "GroupBy query" that would allow you to fetch the data the way you would like.
If you are just using the API you can use the schema documentation to search if there is a query format that satisfies your need.
You can also make your own groupBy function after fetching the data, there's some good examples in these answers.

Prettify GraphiQL query: filter always formatted in one long unreadable line

I prettify my GraphQL query in the GraphiQL window of my browser. I use the Gatsby GrapiQL implementation. The filter part is always condensed in one long line so that I have to use the horizontal scroll bar. This has been bugging me for months now.
The prettyfied code
{
allFile(filter: {sourceInstanceName: {eq: "tour-data"}}, sort: {fields: base, order: ASC}) {
edges {
node {
relativePath
}
}
}
}
How it looks in the browser: Without scrolling I cannot see or edit how it is sorted.
It's a small inconvenience but this scrolling adds up over time. Prettify implemented like this has terrible user experience. I filter all my queries so I have to do a lot of scrolling.
I looked in the official documentation and the github project. I did not find a way to alter the formatting rules.
Is there a way to tell prettify to give the filter its own lines?
I don't think there's any way to configure that unless you built an instance of GraphiQL yourself and pointed it at your endpoint. You might try a client like Altair though no promises.
The other option is to simply make filter a variable. I think the prettify works a little better on the variables JSON object in that regard.
query ($filter: FileFilterInput!, $sort: FileSortInput!) {
allFile(filter: $filter, sort: $sort) {
edges {
node {
relativePath
}
}
}
}
{
"filter": {
"sourceInstanceName": {
"eq": "tour-data"
}
},
"sort": {
"fields": "base",
"order": "ASC"
}
}
I'm guessing at the actual type names -- check the schema docs for the correct names. Also bear in mind that variables can't be used with StaticQuery.

GraphQL: Explore API without a wildcard (*)?

I am new to GraphQL and I wonder how I can explore an API without a possible wildcard (*) (https://github.com/graphql/graphql-spec/issues/127).
I am currently setting up a headless Craft CMS with GraphQL and I don't really know how my data is nested.
Event with the REST API I have no chance of just getting all the data, because I have to setup all the endpoints and therefore I have to know all field names as well.
So how could I easily explore my CraftCMS data structure?
Thanks for any hints on this.
Cheers
merc
------ Edit -------
If I use #simonpedro s suggestion:
{
__schema {
types {
name
kind
fields {
name
}
}
}
}
I can see a lot of types (?)/fields (?)...
For example I see:
{
"name": "FlexibleContentTeaser",
"kind": "OBJECT",
"fields": [
{
"name": "id"
},
{
"name": "enabled"
},
{
"name": "teaserTitle"
},
{
"name": "text"
},
{
"name": "teaserLink"
},
{
"name": "teaserLinkConnection"
}
]
But now I would like to know how a teaserLink ist structured.
I somehow found out that the teaserLink (it is a field with the type Entries, where I can link to another page) has the properties url & title.
But how would I set up query to explore the properties available within teaserLink?
I tried all sorts of queries, but I am always confrontend with messages like this:
I would be really glad if somebody could give me another pointer how I can find out which properties I can actually query...
Thank you
As far as I'm concerned currently there is no graphql implementation with that capability. However, if what you want to do is to explore the "data structure", i.e, the schema, you should use schema instrospection, which was thought for that (explore the graphql schema). For example, a simple graphql instrospection query would be like this:
{
__schema {
types {
name
kind
fields {
name
}
}
}
}
References:
- https://graphql.org/learn/introspection/
UPDATE for edit:
What you want to do I think is the following:
Make a query like this
{
__schema {
types {
name
kind
fields {
name
type {
fields {
name
}
}
}
}
}
}
And then find the wished type field to grab more information (the fields) from it. Something like this (I don't know if this works, just an idea):
const typeFlexibleContentTeaser = data.__schema.types.find(t => t === "FlexibleContentTeaser")
const teaserLinkField = typeFlexibleContentTeaser.fields.find(f => f.name === "teaserLink")
const teaserLinkField = teaserLinkField.type.fields;
i.e, you have to transverse recursively through the type field.

AppSync - query for all items created within a date range?

I'm trying to query my items (which have fields of AWS DateTime of CreatedAt and UpdatedAt) for all within a certain date range. For example, the past 48 hours.
For example, using this schema:
type Note #model #searchable #auth(rules: [{ allow: owner }]) {
id: ID!
note: String
createdAt: AWSDateTime
I'm able to search for dates using, for example:
query {
searchNotes(filter:{createdAt: { matchPhrasePrefix: "2018-12-27"}}) {
items{
id
title
createdAt
}
}
}
Which returns all notes that match the UTC time with that string prefix.
From which, I have to sort myself using moment.diff(), or some other method.
I'm not sure there is a better/more efficient way of doing searching/filtering by dates and time using AppSync and GraphQl?
Thank you.
You can use this query to filter 2 AWSDateTime:
query {
searchNotes(filter:{createdAt: { between: ["2018-12-27T00:00:00", "2019-01-27T00:00:00"]}}) {
items{
id
title
createdAt
}
}
}
As of writing (Jan 3, 2019), the easiest way to do this would be to store the date as an integer (e.g. seconds since epoch) which would open up the gt, lt, gte, ... filter fields on the auto-generated search resolvers filter input.
Another solution is to write your own resolver using the AWS AppSync console or your own CloudFormation stack. When writing your own resolver you can leverage the entire Elasticsearch DSL to implement all kinds of queries (see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html). To go down this route, you can add your own search field to the Query type in your schema and write a custom resolver.
type Query {
searchNotesByCreatedAt(start: String!, end: String!): NotesConnection
}
Then via the console or via your own CloudFormation stack you can write a resolver like this:
{
"version": "2017-02-28",
"operation": "GET",
"path": "/note-<your-api-id>/doc/_search", // created by amplify
"params": {
"body": {
"sort": [{ "createdAt" : {"order" : "desc"}}],
"query": {
"range" : {
"createdAt" : {
"gte": $ctx.args.start,
"lte": $ctx.args.end
}
}
}
}
}
}
You will only need to deploy this resolver using the console or your own CF stack temporarily. Work is being done to allow you to write your own resolvers from within the amplify CLI. For more information on how this will work see https://github.com/aws-amplify/amplify-cli/issues/574.
Let me know if this works for you.

Gatsby and GraphQL - How to Filter Array Within Query

I started using Gatsby along with GraphQL to return a query that lists all galleries that are part of a specific category. In this example the category is called "Lifestyle". This all works successfully and I get an array with all of the Galleries in the category. I also need to sort this array based off a sub field called "date". Is that possible to do via the GraphQL query itself? I tried adding (sort: { fields: [date], order: DESC }) to the gallery field but that didn't work.
Any thoughts on how to achieve this or is this as close as GraphQL can get me to what I need?
Thanks in advance for any help. Still trying to wrap my head around GraphQL.
Ryan
Example of my current query
Could you provide a bit more details about your content model?
If you use a "Reference" field in contentful, it is sadly not possible as of now with the plugin as far as I know.
If you use a "Short text, list" field, like the tags in the default example.
With the default example, you can do the following query:
{
allContentfulPost(filter:{tags:{eq:"fantasy"}}, sort:{fields:[date], order:DESC}) {
edges {
node {
title {
childMarkdownRemark {
html
}
}
slug
date
}
}
}
}
It will give you the following result:
{
"data": {
"allContentfulPost": {
"edges": [
{
"node": {
"title": {
"childMarkdownRemark": {
"html": "<p>Disney Movie</p>"
}
},
"slug": "down-the-rabbit-hole",
"date": "2017-11-26"
}
},
{
"node": {
"title": {
"childMarkdownRemark": {
"html": "<p>Old book</p>"
}
},
"slug": "down-the-rabbit-hole-2",
"date": "1865-11-26"
}
}
]
}
}
}
I came across this same issue as I was trying to sort posts from a category tag that I was using in Contentful. Like #chmac said, you can sort the data from GraphQL with Javascript.
I had to search for a good example, but I finally found one in this Gatsby starter:
Github: https://github.com/ryanwiemer/gatsby-starter-gcn/blob/master/src/templates/tag.js
Live Example: https://gcn.netlify.com/tag/fancy/
You can see in the source file that they sorted the data in a new constant called posts using moment (https://www.npmjs.com/package/moment) and lodash. In my personal example I had to tweak my constant like so:
const courses = orderBy(
this.props.data.contentfulCategory.course,
// eslint-disable-next-line
[object => new moment(object.createdAt)],
['desc']
)
Then I just used a map function like so in the component return:
{/* Courses */}
{courses.map(course => (
<div className="hero__profile" key={course.id}>
<h2>{course.title}</h2>
</div>
))}
I hope this helps!

Resources