0

I'm developing a backend-for-frontend (BFF) solution for a web client with apollo graphql

Use-case background, our organization has a general use graphql api that another team owns and my team is creating another graphql server to consume it. This would allow us to offload heavy computations from the client. We are also hoping to have a combined schema to access the general use api when needed from the same endpoint as our BFF.

My questions are:

  1. apollo federation is recommended for combining schemas, however, it strongly recommends that federated servers are private behind a firewall due to the power of the _entities field. Why is that and would it be a concern if the data is not sensitive user data? We'd prefer to keep all servers public.
  2. apollo schema stitching may actually fit our use case better since it does not make note that any api be private. It also may make DataSource logic more streamlined for the computations we need to make. However, most documentation I see are about migrating FROM schema stitching. Is schema stitching to be deprecated in the near future?
  3. is there another option that seems like it would fit the bill better that I have missed?
jVERM
  • 131
  • 1
  • 5

2 Answers2

0

Hiding your federated services is not a must do, its more of a recommendation.

If you have a single combined schema, then why would you expose the non-combined individual schemas?

Also if you allow clients to interact with individual services, it is more difficult to manage logs and rate limiting also becomes more difficult.

When you use combine multiple graphql schemas, you also probably refer to each other, or service A could add fields to service B, etc. Querying these fields will be sort of broken if you use individual services. (but it will still work, just missing fields)

And yes schema stching is being deprecated. Apollo recommends developers to use apollo federation instead.

One thing to note though, apollo federation does not support subscription yet, so if subscription is a must right now, then you should stick with schema stiching until subscription is released.

Sihoon Kim
  • 1,481
  • 2
  • 13
  • 32
  • Schema stitching hasn't been deprecate and I believe it won't be in near future. It's actively being maintained. https://www.graphql-tools.com/docs/stitch-combining-schemas – ardatan May 07 '21 at 14:28
0

To answer your questions:

  1. Why is that and would it be a concern if the data is not sensitive user data?

The _entities query is very powerful, as you said. For example, if you're taking access control shortcuts it can be dangerous. Assume you have private users. If you have auth checks on the Query.user(id: ID), in a non-federated query, you don't have to necessarily put extra auth checks on User.homeAddress, since you can't get to the nested field without having access to the top-level field. Now let's pretend your address service extends the user object. Now I can make this call to the address service endpoint (not through the gateway):

query ($_representations: [_Any!]!) {
  _entities(representations:$_representations) {
    ... on User {
      homeAddress {
        street1
        street2
        city
        state
        postalCode
      }
    }
  }
}
{
  "_representations": [{
    "__typename": "User",
    "id": "user-id-whatever"
  }]
}

And if you did "lazy access control" you're now not protected, because it's never calling the users service for permission first. As an extension to this, you can see it depends on if you're dealing with "non-sensitive" data or "unprotected data".

  1. Schema Stitching already was deprecated for a while. It appears that they've un-deprecated it, since I can no longer see deprecation warnings where I used to see them, but as far as I know, it's "still going away".

  2. Not really, but I also would recommend Federation. Honestly, I've done both in production for a long time, and I've been a big fan of Federation, and I would recommend it for most cases. The only real difference between federation and stitching is that with stitching you have to expose "extra fields" from your backing services (e.g. to add a user to an object, the service would have to expose userId, which you could then use to stitch a User onto. Federation gets around that by exposing _entities, but it's basically the thing, and Federation does it for you, so you don't have to build the delegation.

Dan Crews
  • 3,067
  • 17
  • 20