GraphQL: creating directives with string comparison - graphql

I'm looking to create a GraphQL query that selectively adds/removes fields based on a variable "type", which is a string:
query ResultsPage($casetype: String!)
According to the reference on Directives, you can use a boolean value to either #include or #skip certain fields:
query Hero($episode: Episode, $withFriends: Boolean!) {
hero(episode: $episode) {
name
friends #include(if: $withFriends) {
name
}
}
}
How could I do something similar with this string value? i.e. only include the friends field if $casetype = "foo". Is this possible with GraphQL?
Thanks!

Unfortunately there is no way to use string comparison. Only way that you can is write custom Directive which can handle on its own.
please check a closed issue here

Related

Query only if non-boolean argument exists

I'm trying to find a way to achieve include multiple queries in the same query based on required arguments.
This might be confusing, so let's take a look at an example
If we have 2 resolvers both with required IDs, let's say:
post(id: ID!) {...}
user(id: ID!) {...}
And we want to fetch both within the same query/request, but we might or not have an ID like the user, something as:
query($postId: ID!, $userId: ID) {
post(id: $postId) { ... }
user(id: $userId) { ... }
}
Now if we look we see that $user: ID is not mandatory in the query, but it is in the resolver.
I've looked at #include and #skip directives although, I didn't find a way to convert the $userId to a boolean.
Also, I've tried to pass a boolean as shouldIncludeUser although, as expected, the GQL will complain that the variable $userId of type ID doesn't match the type ID!.
Any ideas ?
Is this even possible?

graphql query with certain combination of parameters

I am looking to specify a certain required combination of parameters in a graphQL query.
The query should be valid either without any params and return all cats or filter by size AND species.
extend type Query {
cats(size: String, species: String): [Cat]
}
Is the only way to do this via the resolver (throw error if one arg is passed) or is there a neater way?
I don't believe that this is defined in the spec. You could define a new input type and then use this though.
input CatFilter {
size: String!
species: String!
}
extend type Query {
cats(filter: CatFilter): [Cat]
}
That way the parameter is optional, but if given, both properties are required.

Graphql include directive

I have a query that takes a status as an input variable which is an enum of (future, past, all).
I'd like to return some fields only when the status is future. I've tried using #include but it seems it will only accept a boolean exactly.
Is there some way of getting this to work:
aField #include(if: $status == future)
I think you can't use even use boolean fields with #include - literals/query variables only, so expressions are a no-go as well.
If it's really important, and you're able to modify the API/schema, you could (ab)use the interface functionality - have future entities resolve to one type, and past entities to another, then you can use fragments to select fields based on which it is:
interface Competition {
id: ID!
name: String!
status: Status!
something: String
}
type FutureCompetition implements Competition {
// same fields
}
type PastCompetition implements Competition {
// same fields
}
Then you can query with something like this:
competitions {
id
name
status
... on FutureCompetition {
something
}
}
A possibly easier thing to do would be to simply do two queries in one and merge the results client-side, assuming you can query by status:
pastCompetitions: competitions(withStatus: PAST) {
id
name
status
}
futureCompetitions: competitions(withStatus: FUTURE) {
id
name
status
something
}
variables is a JSON. So, you can also try passing the status : inputStatus==='FUTURE' ? true : false

GraphQL - fetch a field conditionally

Imagine that I have a following query (I am using Apollo):
const userQuery = gql`
query {
user {
id
name
}
}
`;
I want to fetch name field only if some condition is met (let's say variable shouldFetchName is true). How should I approach this and what is the best practice?
You can pass a variable to your query and use a Directive to fetch a field conditionally, like name #include(if: $shouldFetchName).
See the docs for Directives.

How to search string values in GraphQL

How do you query using GraphQL in a manor similar to SQL's like operator?
Example: What users have a first name starting with jason?
select * from users where first_name like "jason%"
The short answer is: you don't.
The longer answer is that you have to write that code yourself. GraphQL isn't a database query language like SQL, it's an application query language. What that means is that GraphQL won't let you write arbitrary queries out of the box. It will only support the types of queries defined in your GraphQL schema.
If you want to be able to write a query that contains like, you have to
a) declare that in the schema, and
b) write a resolve function that fetches the data
For example, you could have this schema:
type Query {
users(firstName: String!): [User]
}
type User {
firstName: String
lastName: String
}
You would have to define the following resolve function for the users field:
{
Query: {
users(root, args){
return sql.raw('SELECT * FROM `users` WHERE `firstName` LIKE ?', args.firstName);
}
}
}
And finally write this query to get a list of firstName and lastName of all the users that match your search criteria:
{
users(firstName: 'jason%'){
firstName
lastName
}
}
Here's a post I wrote a while ago that clarifies some of the concepts around GraphQL: https://medium.com/apollo-stack/how-do-i-graphql-2fcabfc94a01
And here's a post that explains the interplay between GraphQL schemas and resolve functions: https://medium.com/apollo-stack/graphql-explained-5844742f195e
Not sure if this is relevant to you because you want it to start with "jason" (ie would return "jason bourne" but not "bourne jason") but I recently came across a way to query GraphQL in a "%Like%" manner. For your use case it would look something like this:
export const allUsersQuery = `
query allUsers($UserName: String!){
allUsers(
filter: {first_name_contains: $UserName}
) {
id
first_name
...INSERT_OTHER_FIELDS_HERE...
}
}
`;
FWIW: I did this using a GraphCool BAAS. I don't think you were using GraphCool because GraphCool doesn't allow "_" in variable names.
Hope this helps someone down the line :)

Resources