Open MoonTahoe opened 5 years ago
@MoonTahoe (👋 Alex!) This is a really great question 👍
The tldr; is this isn't supported right now 😭
The exciting answer is this is on the roadmap 🎉 This is what it would look like:
type User @key(fields: "id") {
id: ID!
name: String
username: String
productsPurchased: [Product] @internal
totalDollarsSpent: Float @requires(fields: "productsPurchased { price }")
}
extend type Product @key(fields: "upc") {
upc: String! @external
price: Int @external
}
A couple things introduced here (that will come in multiple releases):
@internal
directive. This will probably come first in the scheme of things. Internal will allow for hiding fields from the overall schema that the client can consume.
@requires
support when used on a base type. This will come a little bit later because it complicates the query planner a good bit 😆. Ultimately the query plan would be something like this:
{
me {
totalDollarsSpent
}
}
{
me {
id
productsPurchased {
upc
}
}
}
{
... on Product {
price
}
}
{
... on User {
totalDollarsSpent
}
}
{
totalDollarsSpent: ({ productsPurchased }) =>
productsPurchased.reduce(({ price }, prev) => price + prev, 0)
}
That is really cool. This is sort of how I was trying to use ‘@requires’ at first.
any updates in this?, looks like a feature that we will like to use in my team :)
@MoonTahoe Thank you for bringing this to my attention. This is in the same vein as https://github.com/apollographql/apollo-server/issues/3621 and other concepts like "@scope", if I'm reading this thread correctly.
I wonder late into the evenings how far GraphQL's concerns should ultimately extend to all of these cases: perhaps it's the expressive, declarative, type-safe nature of GraphQL that causes us all to "lean in" to applying GraphQL to all patterns instead of insisting that its properties (expressive, declarative, type-safe) exist in other systems. Swagger/OAS helped to make great strides in REST, and these are all "echoes" of SOAP, CORBA, and similar attempts at ensuring that systems can be statically-analyzed, descriptive, and discoverable. JSON API and oData have some of these characteristics as well as an API layer. Traditional RDBMS's have always strongly-typed for their internal reasons and efforts to bring this into the ORM layer never really connected all of the dots (unless I'm missing a key implementation somewhere).
With all of this context, I'm going to add this to my list of considerations as we discuss the next steps on this kind of "scoping" of a single graph.
Thanks for looking into this @jhampton. Right now the primary solution for this requirement is to send a graphql-request
from the resolver, which feels a little like stitching. I like the above solution that @jbaxleyiii presented. It looks like a sweet solution to merge that request in with the query plan as opposed to making an additional graphql-request
from within a resolver.
I have the same problem, but with a Mutation that requires some extra data for checking some stuff, I tried to find some pretty solutions in the blog and the documentation, but I didn't find anything so far. In this case, we will decide to use graphql-request
pointing to another graphql service. The question will be:
I will glad if someone Can add some inputs or experiences how we must resolve these situations
Hello sir @jbaxleyiii is there an update on this one? thank you
Please do if possible share the best practice in current spec to access additional data across services.
If you're interested in how Apollo Federation can handle cross-service mutations, check out this repository Apollo-Federation-Mutation-Demo. It provides a practical example of accessing external data in a seamless way.
It seems that the requires
directive has been added and this issue has been fixed.
https://www.apollographql.com/docs/federation/federated-types/federated-directives#requires
Federation is great! I love it! This demo is also awesome, thanks! I do have one question about obtaining data from external services.
Let's say I work on the Accounts team. We're using Apollo Federation and have teams working on independent federated services. All of our teams are totally independent, we cannot request features from other teams. If we want to implement something, we have to do it on our own.
Our customers want a running total of the products that they have purchased. We have saved a list of
upc
codes locally for each purchase that a user has made. A user account record has the following data in our database:So we are going to add a field that will resolve to the total dollars that a users has spent on all of the products:
However, when I get to the resolver I do not have enough information about the products that the user has purchased. I only have their UPC codes:
I'm not sure this is even a case for federation, but I was thinking about all of the use cases for teams who work in complete isolation. Federation gracefully handles every other use case that came up, so I though this may be in the ballpark.