I understand the principles of querying via graphql from the docs you could search:
{
"hero": {
"name": "R2-D2"
}
}
but how about you want to do something a bit more intricate such as:
{
"hero": {
"name": "R2-D2 AND C-3PO AND BB-8 NOT K-2SO"
}
}
is there any way to pass a string like this and get the appropriate results?
No, there isn't.
You can read through the GraphQL spec and see what it does and doesn't define. In particular the spec doesn't define any sort of filtering, any sort of expression language, or any sort of Boolean combinators. (There is no native way to say the equivalent of SQL's WHERE NAME='foo' without a field resolver explicitly adding it.)
What GraphQL allows for field arguments is sufficiently open-ended that you can build richer queries on top of it, but that's very specific to some application or library. Two prominent examples are the GitHub GraphQL API (which tends to allow exact-match queries on selected fields but nothing richer) and the Prisma API (which has an involved multi-level object scheme to replicate SQL queries).
Related
I've got a requirement to move complex switches logic from UI layer to GraphQL layer. This complex switches logic is to perform a computation based on a bunch of backend configurations to determine whether a set of UI components should be shown or hidden. To show or hide a particular UI component in the set, it requires at least 3 levels deep of nested if-else branches logic. I'm currently thinking of adding the following type to the schema to solve this problem:
type MyComplexView {
componentAShown: Boolean!
componentBShown: Boolean!
# ... (gazzillion of other components here)
componentXShown: Boolean!
}
...and then I'd expect the data returned from the query would look something like:
{
"data": {
"myComplexView": {
"componentAShown": true,
"componentBShown": false,
// ... (gazzillion of other components here)
"componentXShown": true,
}
}
}
But it just doesn't feel right, and it feels like I'm abusing the GraphQL layer for doing this kind of job.
So question is, is this also a valid use case for making use of GraphQL? Is there an alternative or better way of doing it? The idea is to share the complex switches logic for all the clients (e.g. web and mobile) that are going to consume the API without re-writing/duplicating the logic again on the client-side.
When using aggregation pipeline with mongo in spring-data, we often face complex pipelines. In these scenarios, the Aggregation class provided by spring-data doesn't cover all the possible queries. Granted it covers more queries/functionalities now than when I started using over two~three years ago.
Example of a Document.parse vs Aggregation
Aggregation.newAggregation(
// Document.parse here
aggregationOperationContext -> Document.parse("{ $match: { 'field': " + value + " } }"),
// Aggregation here
Aggregation.match(field, value)
);
These are the list that I came up with about benefits of each method:
Benefits of using Document.parse():
What you write in the query to be parsed, it's what the java driver will utilize. There is less middle-man here.
Allow complex queries (could be good and bad. I've seen people making complex queries while a simple query would've achieved the same result)
Benefits of using Aggregation provided by spring-data
Succinct syntax
Less likely to errors from typos
My point for posting here is that often time, my team and I discuss if there is any real advantage of using the Aggregation class over tossing the Document.parse() with what we need. Is there other things that I didn't list above? Like, performance, easy of testing, etc? I couldn't see in their source code anything obvious to me. Thank you!
I want to implement a data structure that allows for powerful filtering within my application.
The closest implementation I've found is from Prisma https://www.prisma.io/docs/1.27/prisma-graphql-api/reference/queries-qwe1/#combining-multiple-filters (which is actually from GraphQL specification, for what I understand)
Example:
{
OR: [
{
AND: [
{ title_in: ["My biggest Adventure", "My latest Hobbies"] }
{ published: true }
]
}
{ id: "cixnen24p33lo0143bexvr52n" }
]
}
The idea is to compare a context against the filters and see if it's a match.
In the above example, the "context" would be an object with the id, title and published fields.
I'm looking for an algorithm that would perform the comparison and resolve whether it's a match or not.
As I'm not looking at reinventing the wheel (especially that it's a complex algorithm IMHO, as AND/OR/NOT conditions can be nested), I wonder if that particular algorithm already exists, or is based on some standards (as we can find that particular data structure on several apps, such as Prisma, PipeDrive and other).
I'm looking for documentation, implementation examples or even open source implementations. (I'm using JS)
I was also looking for such an implementation but couldn't find one.
So I created a prototype for it: https://github.com/Errorname/logical-object-match
We couldn't find a solution that matched our requirements, so built our own and released it as OSS (MIT).
https://github.com/UnlyEd/conditions-matcher
Compares a given context with a filter (a set of conditions) and resolves whether the context validates the filter. Strongly inspired by GraphQL filters.
I've been looking around to see if a pattern exists for merging two graphQL datasets which contain the same type of data. What I mean is, given the following two type definitions;
type StevesBooks {
title: String
author: String
}
type DavesBooks {
title: String
author: String
}
If both of those are implemented as graphQL schemas separately/remotely, each with their own set of resolvers, is there a pattern or paradigm I can draw from to create a third graphQL instance that combines these two, so I can query "SteveAndDavesBooks" at the same time?
I found mergeSchemas in the apolloServer API but that solves a different problem to this one and all of the conflict-resolution methods in there require you to "choose a side" so to speak, rather than combine the results.
Is there already-written plugin or library somewhere that will help to achieve the above or do you think this is going to be something bespoke that I need to do myself?
I saw that query federation is on the roadmap - does anyone know any more details about that because that sounds like what I'm after.
I'm building a Graphene-Django based GraphQL API. One of my colleagues, who is building an Angular client that will use the API, has asked if there's a way to store frequently used queries somehow on the server-side so that he can just call them by name?
I have not yet encountered such functionality so am not sure if it's even possible.
FYI he is using the Apollo Client so maybe such "named" queries is strictly client-side? Here's a page he referred me to: http://dev.apollodata.com/angular2/cache-updates.html
Robert
Excellent question! I think the thing you are looking for is called "persisted queries." The GraphQL spec only outlines
A Type System for a schema
A formal language for queries
How to validate/execute a query against a schema
Beyond that, it is up to the implementation to make specific optimizations. There are a few ways to do persisted queries, and different ones may be more or less helpful for your project.
Storing Queries as a String
Queries can easily be stored as Strings, and the convention is to use *.gql files to do that. Many editors/IDEs will even have syntax highlighting for this. To consume them later, just URL Encode them, and you're all set! Since these strings are "known" you can whitelist the requests on the server if you choose.
const myQuery = `
{
user {
firstName
lastName
}
}
`
const query = `www.myserver.com/query=${urlEncode(myQuery)}`
Persisted Queries
For a more sophisticated approach, you can take queries that are extracted from your project (either from strings or using a build tool), pre-run them and put the result in a DB. This is what Facebook does. There are plenty of tools out there to help you with this, and the Awesome-GraphQL repo is a good place to start looking.
Resources
Check out this blog for more info on Persisted Queries