GraphQL - Difference between using alias versus multiple query objects when doing batch queries - graphql

I'm fairly new to GraphQL, so please correct me if I'm wrong where need be. I'm wondering what would be the best way, or the most appropriate way, to execute batch queries in a single request. I've seen examples that do this:
[
{
query: "query(param1)"
},
{
query: "query(param2)"
}
]
Or examples that use aliases to accomplish the same thing:
query {
alias1: resolver1(param1)
alias2: resolver2(param2)
}
In my opinion, I think the aliases is the more appropriate option as it's a single query and within that query I'm requesting data with different parameters. So, between the two options above, what would be the more appropriate option for executing batch queries in GraphQL, and why? Thanks!

Batching operations by sending an array of them to the server is something that's not supported by all libraries. This is not a feature of GraphQL as much as just a convenient feature supported by some server libraries. On the other hand, including multiple root-level fields in a single operation is supported by all GraphQL servers. So, if you're anticipating the backend you are querying to possibly change in the future, you may want to use Option #2 over Option #1 to avoid having to potentially refactor your code in the future.
On the other hand, batching is often desirable because it allows you to mix operation types. While you can include any number of root-level fields in a single operation, only one operation may be executed at a time -- that means you can't mix queries and mutations with Option #2. If this is something you need to do, batching is the only way to achieve it in a single request (assuming your server supports it).

Related

Consuming FHIR Client API with SQL-like ideas

I'm new to the FHIR World, I have a FHIR client, HAPI FHIR that I can use to fetch data through a restful API. I apology if I missunderstand something during my FHIR documentation journey.
I've look around the documentation and tried some requests to fetch basic data, like a list of Patient, an Observation by id etc..
In my case, I need to get a list of Patient that have the same name as its resource generalPractioner (it's unlikely to happen, it's just an example).
In regular SQL it would look like something like this :
SELECT * FROM Patient
INNER JOIN Practitioner ON Practitioner.id = Patient.practitioner_id
WHERE Patient.name = Practitioner.name
Since FHIR doesn't work that way and isn't relational database, I need to come up with a way to do the equivalent of SQL's WHERE and SQL's JOIN but through the restful API of the client.
My questions are : Is it possible to do these kind of thing directly on a FHIR Client through the API ? If yes, do I need to make new modules inside HAPI FHIR (JPA or plain server ?) (using Java) so it can understand what I really want ?(a new parser with a new route on each resource for example).
Note that the example with the SQL query is pretty simple, my project is to be able to do really nested joins and wheres, as well as the SQL's AND and OR. It doesn't have to use graphQL, this is just what matches the most with my idea while I was reading the documentation.
I'm afraid that regular _include, _filter and _search parameters aren't enough for what I need.
I found that the fhirpath thing could be use but I didn't find how to use it through the API (except with the $graphql operation).
Seems like ChatGPT want me to use the operation $fhirql which is no longer supported in the recent versions of HAPI FHIR, this seemed to be wnat I want.
Thanks !
I do not know what $fhirql is - and I think I know everything there is to know about FHIR. And Google comes up blank, so that might be ChatGPT just fantasising again. Maybe it invented that based on https://github.com/FirelyTeam/FhirQuery, which is clearly the kind of thing you're thinking about.
Or maybe Pathling is closer to what you want: https://pathling.csiro.au.
$graphql only lets you filter your data, it doesn't allow de novo new joins. _filter is the nearest to what you want, for the few servers that support it, but even then, no joins the way you want.
So it looks like you'll have to fetch the data from your API by a client, and then do something locally, which is how those tools work. Unless the server does something specific for you

How to use a Apollo GraphQL query result as the input of another one? Aka: request chaining

I know this has been asked a couple of times before, but I have found no definitive solution to whether this is possible with GraphQL. And I have a strong feeling this should be possible as it should be relatively easy to implement due to GraphQL queries running sequentially in Apollo.
I have a situation where I'm doing a GraphQL mutation first on the client, and then immediately after doing a query which uses the results from the previous query. This causes a needlessly long response time waiting for the server to respond to both requests. The requests look like this:
mutation createWebSession($authId: ID!) {
webSession: createWebSession(authId: $authId) {
token
userId
}
}
query listUserPaymentMethods($userId: ID!) {
userPaymentMethods: paymentMethods(userId: $userId) {
id
}
}
I know that one simple band-aid solution to avoid making 2 round trips to the server is creating a new single GraphQL mutation endpoint that does both services on the back end. But that seems to defeat the purpose of writing modular, reusable GraphQL endpoints. As such, I'm curious if someone knows if Apollo GraphQL supports a cleaner way to chain 2 requests in which the results from the previous one are available to the next one as inputs.
Any help would be greatly appreciated, thanks.
This is a limitation that specific to GraphQL in general. There is no way to do this in a single request for a couple of reasons:
While a GraphQL document may include any number of operations, only a single operation will be executed. If a document includes multiple operations, all operations must be named and the request must include an operationName parameter that specifies which operation to execute. In other words, while you can combine multiple queries into a single operation, or multiple mutations into a single operation, you cannot cannot mix-and-match queries and mutations.
Given any two fields that share the same "parent" field, both fields will resolve at the same time. The only exception to this are root level mutation fields, which do resolve in sequence. As such, GraphQL does not support any syntax that would let you reference another field and use it as the input to some argument.
One possible workaround is to include a field in your createWebSession payload type whose field is the Query type. I illustrate this approach in this article as a means of refetching queries but it would work for what you're trying to do as well.

How can I use a single url parameter for multiple queries in google data studio?

I'm using Google Data Studio to visualize results from various queries (from different tables within the same BigQuery-database).
For this reason, I created and use multiple data-sources-connectors. Each one of them has a SQL query included and makes use of an defined input parameter (which can be changed by report editors) - called "userid". It is the same id for all queries and resulting charts.
However, when I click "Manage URL parameters", I'm not allowed to use the same URL parameter for more than one data source (instead they are called ds0, ds1, ds2 etc - although they all end up being used as "userid").
If I add a data source under File - Report Settings, a new field "userid" appears, which I can alter - this will update ALL charts in the report with the very same userid (as expected). This works, but I do want to make use of an url which delivers an report with all updated queries depending on ONE userid.
Therefore, I guess I'm overseeing something - it should be possible to just use one query parameter to update the same "userid" for all queries in all data connectors? Or have I overlooked the possibility to fire multiple queries within one data source connector? Or is it expected to create a looong url full of redundant query parameters in this case?
I'm curious for your input!
Best regards :)
There does not seem to be any good solution for this.
For now the best workaround seems to be to just repeat the parameter multiple times -- it's ugly but it works. For example, use the URL parameter mapping screen to call the parameter u1, u2, etc., and then just pass all of them:
?params={"u1":"foo","u2":"foo"}
(URL encoded of course)
The ugliness is mostly for us developers: it violates our sense of DRY and clean code, and makes the URL much longer than it needs to be. However, most people don't care or know about the URL parameters so its irrelevant to them.
The bigger downside is that when the URL is distributed to clients (bookmarks, mobile apps), every time new data sources are added that require the same URL parameters, a new URL has to be distributed to clients for no good reason. A workaround for this is to build the URL dynamically via a simple redirector function.
This issue https://issuetracker.google.com/issues/180705297 is a feature request to implement this capability.
If you group the elements that you want to control with the same parameter (select and then shift G) then it will give you options to select the data source and the params box to apply to the group.

How to reduce request body in Elasticsearch

Sometimes I'm facing too big Elasticsearch queries with duplicated parts with applying the same filtering structure into aggregations (for every aggregation field). Such queries are too massive for inspecting them. Is there any way to decrease request body size? A kind of aliases maybe, I need something like variables in YAML. Or maybe you could suggest something else. Thanks!
Please have a look on search templates. You'll be able to store query templates in the cluster, use variables and even build dynamic queries:
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-template.html
Using this feature will reduce your request body dramatically as you'll just refer a pre registered template, providing some parameters if needed.
Repeating blocks and conditional sections are possible using mustache templating language http://mustache.github.io/mustache.5.html
Have fun!

Searching for two resource types and sorting according to date?

Is it possible with a FHIR search procedure to search for TWO resource types and sort them according to the date? I'd like a list of Observation and QuestionnareResponses, in a single response, returning the newest 10 regardless of resource type.
Searching for one would be:
http://apps.ehelselab.com/baseDstu2/Observation?_sort:desc=date
Any query using the standard "search" capability is always against exactly one resource type. You can include referencing and referenced resources, but filtering and sorting are always done against the "base" resource for the search. To do what you're interested in doing, you have a few options:
define a custom query using the OperationDefinition mechanism (only works if you've got a direct relationship between client and server systems so you can ensure all participants support the operation
Use a "Batch" to execute queries against both, then interpolate the results as you page through both result sets
You can do a query just on the "base", however there isn't presently a way to constrain the types of resources returned - you'd need a custom search criteria
You might be able to use the _filter mechanism - I haven't dived into it very deeply. But I suspect that it also uses the "single target resource type" approach.
The best bet is probably #3. If you submit a request to add a search criteria to "Resource" allowing constraining the resource type, that would probably let you do what you wanted.

Resources