cant use any filter parameters on graphql in strapi - graphql

I have been unable to use any of the filter parameters on graphl query in strapi using the url (http://localhost:1337/graphql). I am using strapi 3.6.8 . I have a collection (Animals) that has an array of Habitat. When I try to limit the number of Habitat returned for each record to 3, it doesn't work with the query below.
query{
Animals {
id
Habitat(limit: 3) {
Feature {
Weight
Height
Lifespan
}
}
}
}
I get the error message: "Unknown argument "limit" on field "Animal.Habitat"."
the limit, where or any other filter does not work. They work however when I use them on the Animals itself. Kindly help

If you are on graphql playground, try pressing CTRL + SPACE and you will see the available parameters that you can use inside your query. In your case, I assume you want to use the pagination feature provided by Strapi. The following query should work.
query {
Animals {
id
Habitat(pagination: { limit: 3 }) {
Feature {
Weight
Height
Lifespan
}
}
}
}

Related

How to query a map of id with graphql?

I am trying to query an array of ids with graphQl. The query works with a single id as a variable. However it doesn't work when I enter an array of ids.
Here is my gql query with variables:
query GetAuthorContent($id: [ID]!, $idType: AuthorIdType) {
expert(id: $id, idType: $idType) {
excerpt
featuredImage {
node {
description
author {
node {
description
}
}
}
}
slug
}
}
{"id": ["author-1", "author-2", "author-3"], "idType": "SLUG" }
You can look at the definition of the graphql endpoint using a client and see if the Arrays are supported with query.
If it's supported, check the mutation signature and pass accordingly. In this case I think the services does not support querying using an Array.
Hi everyone and thank you for your help.
You guys were right, my DB doesn't allow an array of authors if it is per author singular. However it works with authors plural. This is the way my db works.
Hope it can help someone in the same situation.

How can I query my data by published date (newest first) using Apollo and Graphql?

I have React page that is fetching data via Graphql.
I'm using Strapi as backend and queries are already generated.
I´m querying my data in the frontend like this
query GetData{
datas(limit:3){
id
published_at
}
}
In the documentation I found this example about how to sort my queries by some especific order
GET /users?_sort=email:ASC,dateField:DESC
but is not really clear how to use it with the query structure.
I tried something like this and other variations
query GetPodcasts{
podcasts?_sort=published_at:DESC(limit:3){
id
published_at
}
}
but it didn't work.
I may need some help understanding this.
In a forum some nice people also gave me an answer.
When using graphql in frontend and want to sort or filter the data, just have to use "" to specify the sort or filter.
In my case it just had to be:
query GetData{
datas(limit:3, sort:"published_at:desc"){
id
published_at
}
}
Graphql is like an Rest Api but with one end point to the server ,
this query with name GetData , point to datas query but you should define this query in the backend.
please watch some tutorials that will guide you step by step.
you can learn more about graphql here
https://graphql.org/learn/
try this:
query GetData{
datas(input:{
sort:{id:"asc"},
data:{limit:3}
}){
id
published_at
}
}
for more info
https://strapi.io/documentation/developer-docs/latest/development/plugins/graphql.html#query-api
This seem to work for me in Strapi v4:
sort: "publishedAt:DESC"
...
query GetVideos($page: Int!, $pageSize: Int!) {
videos(
pagination: { page: $page, pageSize: $pageSize }
sort: "publishedAt:DESC"
) {
__typename
data {
__typename
id
attributes {
__typename
createdAt
publishedAt
}
}
}
}
}
`

How to force a filter on server side to a graphql query?

Imagine the condition that I have a query called "users" that returns all the users and these users can be associated with one or more companies, so I have a type UserCompanies (I need it because it saves some more information beyond the relation). I'm using Prisma and I need to force a filter that returns only users that are of the same company as the requester.
I get the information of the company from JWT and need to inject this to the query before sending it to Prisma.
So, query should be like that:
query allUsers {
users {
name
id
status
email
userCompanies{
id
role
}
}
}
and on server side, I should transform it to: (user where is ok, just changing args)
query allUsers {
users(where: {
userCompanies_some: {
companyId: "companyId-from-jwt"
}
}) {
name
id
status
email
userCompanies(where: {
companyId: "companyId-from-jwt"
}){
id
role
}
}
}
I'm seeing a few resolutions to this, but I don't know if it is the best way:
1 - Using addFragmentToInfo, does the job to put conditions on the query, but if the query has a usercompanies already set, it gives me a conflict. Otherwise, it works fine.
2 - I can use an alias for the query, but after DB result I will need to edit all the results in array to overwrite the result.
3 - don't use info on Prisma and filter in js.
4 - Edit info(4th parameter) of type GraphqlResolveInfo

GraphQL: Use returned value from field as parameter of sub-query [duplicate]

Imagine the following query:
query {
user {
id
}
SomeOtherStuff(id: <--- I want to pass the id obtained from user) {
id
}
}
How do you pass a parameter obtained from one query to another ?
In GraphQL, fields at each "level" of the request are executed and resolved in parallel. In your example, user and SomeOtherStuff are both fields of the same type (the root Query type) -- so they will be resolved at the same time. That means each query essentially is not aware of the other or what the other resolved to.
You would have to handle this kind of scenario client side. In other words, request the user first, parse the response for the id and then make the second request.
Edit: In Apollo, you would utilize compose for this purpose:
const userQuery = gql`query User { user { id } }`;
const stuffQuery = gql`query SomeOtherStuff($id: ID) { someOtherStuff(id: $id){ stuff } }`;
export default compose(
graphql(userQuery, { name: 'userData' })
graphql(stuffQuery, { name: 'stuffData', options: ({userData:{id}={}}) => ({variables: {id}}) }),
)(YourComponent)
I agree with #DanielRearden. You should make type-resolvers so you can go infinitely deep into the graph. I made a simple server example here that shows deep relationships. Because all the noun-fields are references, it goes infinitely deep for any query.
With that server, you can run a query like this, for example:
{
hero {
name
friends {
name
friends {
name
friends {
name
friends: {
name
}
}
}
}
}
}
So, in your example, structure it like this:
query {
user {
id
otherStuff {
id
}
}
}
I was looking for same scenario and landed on this question. You can get it work other way around. It all depends how you have written your graphql resolver and you need to make sure that your database relations are intact. I have got it working like this.

Can graphql return aggregate counts?

Graphql is great and I've started using it in my app. I have a page that displays summary information and I need graphql to return aggregate counts? Can this be done?
You would define a new GraphQL type that is an object that contains a list and a number. The number would be defined by a resolver function.
On your GraphQL server you can define the resolver function and as part of that, you would have to write the code that performs whatever calculations and queries are necessary to get the aggregate counts.
This is similar to how you would write an object serializer for a REST API or a custom REST API endpoint that runs whatever database queries are needed to calculate the aggregate counts.
GraphQL's strength is that it gives the frontend more power in determining what data specifically is returned. Some of what you write in GraphQL will be the same as what you would write for a REST API.
There's no automatic aggregate function in GraphQL itself.
You can add a field called summary, and in the resolve function calculate the totals.
You should define a Type of aggregated data in Graphql and a function you want to implement it. For example, if you want to write the following query:
SELECT age, sum(score) from student group by age;
You should define the data type that you want to return:
type StudentScoreByAge{
age: Int
sumOfScore: Float
}
and a Graphql function:
getStudentScoreByAge : [StudentScoreByAge]
async function(){
const res = await client.query("SELECT age, sum(score) as sumOfScore
from Student group by age");
return res.rows;
}
... need graphql to return aggregate counts? Can this be done?
Yes, it can be done.
Does GraphQL does it automatically for you? No, because it does not know / care about where you get your data source.
How? GraphQL does not dictate how you get / mutate the data that the user has queried. It's up to your implementation to get the requested aggregated data. You could get aggregated data directly from your MongoDB and serve it back, or you get all the data you need from your data source and do the aggregation yourself.
If you are using Hasura, in the explorer, you can definitely see an "agregate" table name, thus, your query would look something similar to the following:
query queryTable {
table_name {
field1
field2
}
table_name_aggregate {
aggregate { count }
}
}
In your results, you will see the total row count for the query
"table_name_aggregate": {
"aggregate": {
"count": 9973
}
This depends on whether you build the aggregator into your schema and are able to resolve the field.
Can you share what kind of GraphQL Server you're running? As different languages have different implementations, as well as different services (like Hasura, 8base, and Prisma).
Also, when you say "counts", I'm imagining a count of objects in a relation. Such as:
query {
user(id: "1") {
name
summaries {
count
}
}
}
// returns
{
"data": {
"user": {
"name": "Steve",
"summaries": {
"count": 10
}
}
}
}
8base provides the count aggregate by default on relational queries.

Resources