On this page of the GraphQL docs it mentions that GraphQL is a communication pattern. What is meant by that?
Is it because GraphQL is another abstraction layer that sits between clients and your API/DB?
What they are trying to say is that there are many compliant implementations of GraphQL making it more of a protocol or communication pattern than a single library. Akin to REST or GRPC, there are many implementations that can communicate.
Related
I have an architecture question and would love to hear from your experience.
in a micro service environment. when 2 graphql API micro services that need to communicate with each other async via some kind of pub-sub mechanism. would you choose a graphql subscriptions? or something like kafka/rabitmq/etc type system.
are there any architectural rules I should follow? any criteria for this kind of decision?
thanks for your comments!
GraphQL isn't necessarily a bad choice for inter-service communication, but it's not what GraphQL is designed and optimized for. For pub-sub in particular, Kafka and RabbitMQ are both popular choices. GraphQL subscriptions can theoretically be implemented over a queue such as Kafka, but this will add some complexity vs just using Kafka. The GraphQL spec doesn't speak much to how subscriptions should be implemented, and open source support is much less complete than for queries and mutations.
Pros of subscriptions for service-service pub-sub:
GraphQL gives you a tool to specify the shape of messages (This could
also be accomplished with schemas like Avro or Protobufs).
GraphQL subscriptions allow subscribers to customize the payload that
they receive
Cons:
It adds complexity to your system vs using Kafka client directly
You will require more engineering cycles
Some questions to consider:
How much time do you want to spend creating your own solution vs using off-the-shelf code?
What aspects of GraphQL would you benefit from?
I'm working on a project that has multiple microservices behind a API Gateway and some of them expose WebSockets API.
The WebApp needs to be able to interact with those APIs.
.
Those WebSocket API can be built with frameworks that have their own protocols, using socket.io or not etc.
The main goal of this reflexion is to be able to scale and keep flexibility on my WebSockets APIs implementation.
I thought about two solutions :
The first one is to simply proxy requests on the gateway, the webapp will have to open a websocket for each microservice, this looks like a design flaw to me.
The other one is to create a "Notifier Service" that will be a WebSocket Server and that will keep outgoing connections with users and be able to bridge the incomming messages and outgoing ones based on a custom protocol. The drawback is that i need to implement a pub/sub system (or find a solution for). I didn't dig a lot into it but it looks like a lot of work and a homemade solution, i'm not a fan of it.
I didn't find articles that give feedback after exposing such an architecture and websockets in production, i was hoping to find some here.
I agree with you that a simple proxy solution seems to be inadequate as it exposes the internal interfaces to the clients. I found two articles which I think are addressing your problem:
The API Gateway Pattern
Pattern: API Gateway / Backends for Frontends
Both talk about the issues that you have already mentioned in your question: Protocol translation is an advantage of this architecture as it decouples the external API from the protocols internally used. On the other hand, increased complexity due to having another component to be maintained is mentioned as a drawback.
The second article also suggests some existing libraries (namley Netty, Spring Reactor, NodeJS) that can be used to implement an API gateway, so you might want to spend some time evaluating these for your project.
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.
We are trying to implement a GraphQL API which wraps the existing multiple Restful backends (say, orders.example.com/apis, catalogs.example.com/apis...). See the idea diagram next:
Is there any existing GraphQL library helping building the GraphQL server achieving this "proxy" functionality? I feel this is essentially a Relay
I get the picture how to design a asynchronous server in ZeroMQ with several workers, but what is the correct way to create a asynchronous client with several workers? I've tried using a pattern similar to the server, using a proxy between a dealer frontend and a dealer backend. However, using this pattern I get bad performance and also seem to lose packets. That design then seems incorrect, so what is a suitable design pattern to use in the client?