Handle private mutations with Apollo federation - graphql

In a micro-service architecture, I do have GraphQL mutations that are deemed to be used by the end-user, and some more that are only internal.
I am planning to move to Apollo Federation. Is there a built-in way to declare a mutation as unexpected, so that it is not accessible to the end-user but can be called by an internal service directly?
I am not sure what the best design for this would be ; I would not want ending up in a situation for which I have to run two different servers for micro services: a public and a private one.

In short: No, there is not a built-in or conventional way to declare parts of your schema as "private." You could devise your own #private schema directive, which could wrap resolvers with an authentication check that requires a service API key rather than a user access token. These mutations would still be visible on in your schema — that is, they will likely appear in any automatically generated API documentation — but they would be effectively unusable by regular users. In this Apollo Server issue, an Apollo dev mentions plans to provide a built-in #internal directive for this purpose, but it doesn't seem to be available yet.

Related

Apollo Server vs Apollo-server-express [duplicate]

I am struggling to understand the added value of Express (or Koa, Hapi, etc) integration with Apollo GraphQL server.
I see it can work in stand alone mode very well (an example: https://medium.com/codingthesmartway-com-blog/apollo-server-2-introduction-efc4026f5654).
In which case should we use it with (or without) integration? What should drive this decision?
If all you need is a GraphQL endpoint, then using the standalone library (apollo-server) is generally preferred because there will be less boilerplate to write (features like subscriptions, file uploads, etc. just work without additional configuration). However, many applications require additional functionality beyond just exposing a single API endpoint. Examples include:
Webhooks
OAuth callbacks
Session management
Cookie parsing
CSRF protection
Monitoring or logging requests
Rate limiting
Geofencing
Serving static content
Server-side rendering
If you need this sort of functionality for your application, then you'll want to utilize an HTTP framework like Express and then use the appropriate integration library (i.e. apollo-server-express).
Apollo Server also includes integrations for serverless solutions AWS Lambda. If you want to go serverless to, for example, get better scalability or eliminate system admin costs, then you would also need to use one of these integrations.

Best way to consume & combine another public apollo graphql apis: federation v schema stitching

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:
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.
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?
is there another option that seems like it would fit the bill better that I have missed?
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.
To answer your questions:
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".
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".
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.

GraphQL, Apollo, Relay … how do they fit together?

When trying to get started with GraphQL, you meet a lot of new terms: Some are related to the concept of GraphQL itself (mutations, subscriptions, …), but there is also an entire ecosystem around it, which – unfortunately – is not always separated clearly from GraphQL itself. However, I find it quite hard to tell where one thing ends, and where the other one starts, and what the differences are, and what is needed when.
So, to name a few of these terms:
GraphQL
Apollo
Apollo Client
Relay
Can you explain maybe in a few sentences what these things (except GraphQL) are, what they are good for, and how they relate to each other (or don't)? And, which important tools / concepts are missing here?
GraphQL The language
GraphQL is a query language. It has a specification that defines the language, schemas and also the execution of GraphQL queries. Learning these things is a great place to start and completely programming language agnostic.
GraphQL implementations
Then there are different GraphQL implementations in different languages that allow you to create a schema and describe how the query resolves to values. Usually these implementations validate the query against the schema that you have defined and take over the execution. Pretty much all of the JavaScript ecosystem uses GraphQL.js but there are many more implementations in other languages.
GraphQL Servers
GraphQL is also transport layer agnostic. That means that usually the GraphQL implementations don't come with an HTTP server. But often we use HTTP to make GraphQL queries, this is why there are some libraries that use these implementations and provide an easy way to create an HTTP server on top (e.g. by providing a middleware for an HTTP framework or coming with a whole server). I think in JavaScript pretty much everyone uses Apollo Server because it brings some more features and it integrates smothly with the Apollo ecosystem and the services offered by Apollo the company.
Apollo Server has also very much popularized the SDL (Schema Definition Language) approach of defining a GraphQL API. With the SDL approach the GraphQL schema is not created using code but by defining the Schema in a special language (also part of the GraphQL spec) and defining single resolver function seperately from that definition. This get's you started quickly but my feeling is that it is not very popular for large APIs. But you can simply pass your GraphQL.js schema to Apollo Server.
GraphQL Clients
When we have a server running we can make queries to the server using a simple HTTP client like the fetch function of the browser. That works pretty well but the power of GraphQL really shines when we use a client that supports caching an automatic query fetching when they are needed. This way we can reach the promised land of declarative data fetching / data dependencies. Facebook has published their own client library that is designed for the unique requirements of a large web enterprise. The library is called Relay and the newer version (breaking from the older version) is usually reffered to as Relay Modern. But Relay is relatively complicated and needs a specific build chain so that GraphQL became really interesting when Apollo released a lighweight client alternative known as Apollo Client. Apollo Client developed a lot over the years and now supports a lot of configuration. Also apollo-react allows to use Apollo Client with React whereas Relay is specifically built for React. With Apollo gaining quite some weight over the years the folks at Formidable Labs have created Urql.
Conclusion
You can use all of these technologies together. Many people simply chose to use the Apollo Ecosystem together, which is probably a solid choice. If you have used Redux before you will probably feel at home using Apollo Client or Urql. If you are building a large app with a performance focus you should consider Relay and understand what contrains this puts on the way you build the GraphQL schema.

What is the best and proper way to user Hasura as a Data Access Layer

I want to use Hasura only as a Data Access Layer behind a NestJs GraphQL server and keep all the benefit of Hasura especially the real time feature with subscriptions.
The idea is to build a more customised API and handle all the business logic before interacting with Hasura.
By doing this, do I have to handle security access myself on Nestjs layer since I have to connect to Hasura server with x-hasura-admin-secret from Nestjs server?
Do you think it is a good approach to use Hasura ?
Is there any other alternatives that use Hasura as a data access layer in a scalable architecture?
Thanks
Of course you are responsible of the security of the NestJS layer, but I guess you mean authentication. If that's true, then it all depends on what authentication you are planning on using.
If you wish to implement the authentication either using JWT or Webhooks (see this article for explanations), I would suggest letting Hasura take care of it, and your additional layer in this case will just forward the requests to Hasura without needing to to provide the X-Hasura-Admin-Secret.
From what I can tell, people are adding a "Hasura layer" to their already existing, or public, GraphQL APIs using their Remote Schemas feature to accomplish Schema Stitching.
Can we know more of why you wish to add the layer? I am pretty sure Hasura offers way of defining custom queries and aggregate queries and from my experience provides ample queries/mutations. Plus it offers other features that you will probably find interesting (subscriptions, events...)

Access datatypes in graphql server from prisma generated client

I'm running prisma side by side with my graphql application API. I can run prisma generate which produces the client side code and everything is great. However a majority of my endpoints on my application API are nothing more than a proxy to the prisma service. For example, I have a basic Font data model that the user should be able to perform CRUD operations on.
As of now I'm manually creating those CRUD queries with hard coded argument. Is there a way I can simply import code from the prisma client to automagically create those CRUD operations?
You cannot do that with prisma-client. It is expected that you will have your own services on top of Prisma layer that includes your simplified REST endpoints or application level GraphQL server, Authorization, etc.
However, if most of the time you are going to do this, then consider using prisma-bindings instead of prisma-client. It has a forwardTo API but it is only gql to gql forwarding.
Note: For express.js, there is a mapping middleware, rest-graphql but has very limited use.
I'm not sure if I fully understand but if you are trying to create CRUD methods on all your datatypes a service like GraphCool might work better than Prisma?
It's older and less customisable than Prisma but does come with Queries and Mutations setup for all your data types.

Resources