Hi, I am a bit a new to Apollo and I have a question about filtering queries, while using Sequelize to connect to SQL Database
Minor example: I have database which has table containing column Birthdate (Datetime). Decided to add Age to Query via JavaScript minor code aka [Date.now() - Birthdate (converted via dateScalar (example from Apollo))] and now I have a question how to add a filter, which uses age, like filter query with people age beyond 18?
Apollo doesn’t take a particularly opinionated approach for how you implement data-fetching to underlying data-sources within your actual resolvers
, but perhaps you’re looking for something like graphql-sequelize
? This isn’t an endorsement as I haven’t used it myself, but it appears to take care of automatically bringing in args
to its query building process when those arguments (e.g., your filters) are present.
Thoughts?
so for example, if I follow this example Creating a scalable GraphQL API with MySQL, Node.js, and Apollo - LogRocket Blog, I’d need to replace a usual sequelize function like db.users.findall() with… what? A bit vague readme of this graphql-sequelize, but potential of automatic filtering args like
Users(where: {Name: {equals: ‘John’}}) and in resolver it would look like Query: Users: return db.users.findall(args)
looks very nice, but what about custom data like previously mentioned Age (which is like generated field)? I now have an idea to transform Age to the [datetime.now - Age.years()] and passing it to args (kinda).
But I wanted to ask how to write filters in query. I must in short smth like describe graphql input like
input UsersInput{Name: String, etc… etc…} and then to add to the query like Users(where: UsersInput!) and so then it would like that higher above query?
Also I have a question how to implement filtering a nested query? Like we have type User which has inside it another type like Group with its fields like Name, etc…
So the question is how to make/handle/implement queries like Users(where:{Name:{equals: “John”}AND:{Group: {Name: {equals: “Superheroes”}}}}}?
Again, we don’t have an opinionated approach for the logic that goes into your resolvers. In the future, perhaps we will write more guides like this, but the best approach to build the precise queries you need for to connect to your backend data-sources and make sure they are optimal, including using the right indexes, etc. — differs with each backend data source, payload size, pagination requirements, etc.
Luckily, there are various query builders and projects to help with this. Looking at the example you referred to (i.e., age >= x), I still feel like graphql-sequelize
might accomplish what you want via, for example, the before
hander, which lets you transform the arguments into an appropriate where
.
before: (findOptions, args, context) => {
findOptions.where = { /* Custom where arguments */ };
return findOptions;
},
If the graphql-sequelize
project doesn’t solve your needs, you might want to consider another project, like PostGraphile? There are many out there, including some which are just native GraphQL databases!
Fwiw, we (at Apollo) don’t use graphql-sequelize
in any of our own resolver implementations, but rather opt to just write the code directly into the resolvers that use them by manipulating args
into the where
clause that we want. We primarily do this because our backend datasources tend to vary — they can be anything from an ORD to a S3 bucket to time-series databases to files on disk.