How to query a map of id with graphql? - 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.

Related

GraphQL Tag dynamic table name in query (apollo)

In my app every customer has a own table for its data. Depending on which customer was selected I want to dynamically build the tablename for the Graphql query.
For example:
// Query for customer 1
gql`
query overviewQuery {
customer_1 {
aggregate {
count
}
}
}
`
// Query for customer 2
gql`
query overviewQuery {
customer_2 {
aggregate {
count
}
}
}
`
I have the customer id in my vuex store and want to insert a variable into the query like in the following pseudocode which is not working.
const tblUserAggregateName = `customer_${this.$store.state.customer.customerId`
gql`
query overviewQuery {
${this.tblUserAggregateName} {
aggregate {
count
}
}
`
Is there an option how to do this or how can this problem be solved?
It is not an option to hardcode all different customer queries and selected them on runtime.
Thanks!
In the answers it was mentioned, that it is against best practice to dynamically change the table name of GraphQL queries.
As changing the complete database structure for all clients (they each have a separate Database with a own PostgreSQL schema name) is not an option, I found a solution the looks a little bit hacky and definitely not best practice but I thought I might be interesting to share for others with the same problem.
The approach is pretty easy: I write the query as a simple string where I could use variables and convert them later to the gql AST Object with graphql-tag
const query = () => {
const queryString = `
{
${customerId}_table_name {
aggregate {
count
}
}
}`
return gql`${queryString}`
}
Works, but I you have a better solution, I am happy to learn!
You can supply variables, but they should not be used to dynamically infer schema object names. This violates core concepts of GraphQL. Try this instead:
gql`
query overviewQuery ($customerId: ID!) {
customerData (id: $customerId) {
tableName
aggregate {
count
}
}
}`
Apollo provides great documentation on how to supply variables into a query here: https://www.apollographql.com/docs/react/data/queries/
The backend can then use the customerId to determine what table to query. The client making requests does not need to know (nor should it) where that data is or how it's stored. If the client must know the table name, you can add a field (as shown in the example)

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 approach a GraphQL query that returns a boolean value?

Need to check whether an email is available or taken during the user sign-up process. The goal is to quickly query, using GraphQL, the API server and have it tell us if the email is available or taken.
What is the general best practice on a simple boolean-ish type of situation using GraphQL?
Below is what I have come up with but I am unsure if this is a good practice or not and want to hear feedback on a better practice on queries like this.
Request:
query {
emailExists(email:"jane#doe.com") {
is
}
}
Response:
{
"data": {
"emailExists": {
"is": true
}
}
}
A "query" is just a field on what happens to be the Query type. A field can return any output type, including scalars -- it doesn't need to return an object. So it's sufficient to have a schema like:
type Query {
emailExists(email: String!): Boolean!
}
The only reason to prefer an object type would be if you anticipated wanting to add additional fields in the future (i.e. something other than your current is field).

Query by relationship for GraphQL?

How would you use graphQL to query by a "relational" entity value?
For instance, lets say we have a bunch of person-objects. Each "person" then has a relation to an interest/hobby which then has a property called "name".
Now lets say that we want to query for the name of each person with a specific interest, how would such a query be "conducted" using GraphQL?
Using OData it would be something like Persons?$select=name&$expand(Interests($filter=name eq 'Surfing')).. what would be the equivalent for GraphQL?
There is no one equivalent. With the exception of introspection, the GraphQL specification does not dictate what types a schema should have, what fields it should expose or what arguments those fields should take. In other words, there is no one way to query relationships or do things like filtering, sorting or pagination. If you use Relay, it has its own spec with a bit more guidance around things like pagination and connections between different nodes, but even Relay is agnostic to filtering. It's up to the individual service to decide how to implement these features.
As an example, if we set up a Graphcool or Prisma server, our query might look something like this:
query {
persons(where: {
interest: {
name: "Surfing"
}
}) {
name
}
}
A query to a Hasura server might look like this:
query {
persons(where: {
interest: {
name: {
_eq: "Surfing"
}
}
}) {
name
}
}
But there's nothing stopping you from creating a schema that would support a query like:
query {
persons(interest: "Surfing") {
name
}
}

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