How to migrate REST APIs to GraphQL Apollo Federation - graphql

Planning to migrate my PHP APIs to Graphql using Apollo Federation. After a bit of research, I see it is done using the following way:
My questions are:
Is there any better way to create the federated services so it is not a separate layer (1 for each REST API)? Maybe something close to the previous schema stitching approach where all can sit in one place and be stitched together at the end (instead of a specific federated layer for each service).
If this is the recommended way, how do I deploy this infrastructure? From the diagram, does it mean I have 5 instances running to cover all of the services?
Is it recommended to run Gateway and Federated services all inside one instance (from diagram - 3 servers running in one instance)?

Let me know if it helps.
Federated services are great when you want to break the monolithic structure of the non federated implementation of apollo server. It can be designed by incorporating the micro-service best practices. Instead of blindly having one federated service per rest endpoint, you can have federated services based on the functionality the service is suppose to take care. One service can call multiple rest endpoit. This would provide you better control on scaling, securing and managing services at infrastructure level. An example can be as simple as amazon where item browsing hits will be way more than buying transactions. In this case you can have one federated service which provides browsing data where as another one can for managing transactions. Then you can scale one to multiple instance to handle user load and have additional security in place for the one hadnling transactions.
2 & 3. Yes you would need to have deploy all the components separately. I would recomend to have all the services in the same VPC cluster so that you don't have to worry about network layer security. If the services are deployed across multiple clusters, it will be adding handling firewall and https/tls for every request, which would cause unnecssaery delay becuase of network call. Although it would be in milliseconds but can be easily avoided.

Related

One database per API or shared database for multiple APIs in Microservice

I started reading microservices architecture and got confused with one below point.
Each service should have a separate database.
Does each service mean a single web(rest) api having its own database?
For example if I take motor insurance claim operation as a business scenario where I modelled business domain services in 3 part Insurance claim services , partner (automobile service providers) services and customer services.
Insurance claim settlement operation in claim api will require other information like incident , survey done by an inspector, policy detail , documents etc.
Now I can create 5 web(rest) api in Insurance claim services and will store its data in common db and other services like partner and customer service will have their own web apis and db
What is correct ?
All web api (claimAPI, PolicyAPI, IncidentAPI, SurveyAPI and DocumentAPI) in claim insurance services should have their own db or they can keep data in single data base ?
Thanks.
To follow microservice best practice, it is correct that they should each have their own database and be exposed solely by APIs. This is because every service in your architecture should be independent and de-coupled from other services. If 2+ services share a database, then there may arise problems in operation or upgrade.
One big issue with a shared database is each service would need to trust that another service doesn't modify it's information. But since they all have access to the same database, one of the others could in fact modify the underlying data and make things unstable or insecure.
Further, with 2+ services relying on a shared database, then you're forced to use the exact same database/version with all. You lose the freedom to independently use MySQL for one and MongoDB for another. Even if the same tool is used for all, when you do maintenance or migration on one you're forced to do it for the rest. All this adds up to some coupled services that make them harder to maintain and scale.
you can have common database for all microservices, it is one of the microservices patterns:
https://microservices.io/patterns/data/shared-database.html
https://docs.aws.amazon.com/prescriptive-guidance/latest/modernization-data-persistence/shared-database.html
check those links to see advantages and disadvantages of this approach.

Multiple ApolloServers needed to implement a gateway connecting to REST APIs?

I'm building a graphql gateway service, which merge multiple services into one graph, using Apollo/Node/Express and following the Apollo Federation model. Initially, most of the services I'll be connecting to are REST services.
In all of the examples I find (e.g. here), I see that the gateway project runs multiple instances of ApolloServer, one for every REST service plus one more for the gateway itself, and runs them all using a package like concurrently. Basically the gateway project runs n+1 ApolloServers. Having all of these servers running seems strange to me, but I'm pretty new to this whole ecosystem.
I'm not clear if this is just for demonstration purposes, or is this also how it's implemented and deployed in the real world?
I hope that those were just examples, and are not the expected pattern.
If you need multiple GraphQL Services, each one of those would be served as a separate Domain Graph application, as its own project. Then an additional service (the gateway) would consume all of those applications and expose a single unified GraphQL API.

Separate microservice for database access

I'm managing a very large enterprise application in that I've implemented microservice architecture. Standalone microservices have been created based on business entities & operations.
For example,
User Operations Service
Product Operations Service
Finance Operations Service
Please note that each service implemented using an n-tier architecture with WCF. i.e have separate tiers(which is independently deployable to separate server) for business and data access.
There is a centralized database which is accessed by all the microservices. There are a couple of common entities like 'user' accessed by all the services, so we have redundant database calls in multiple services. More efforts required due to database access from many places(i.e a column rename requires deployment of all the apps)
To reduce & optimize code, I'm planning to create separate microservice and move all the database operations into it. i.e services can call "Database Operations Service" for any database operations like add/update/select.
I want to know if there are any hidden challenges that I'm not aware of. Whether should I go with this thought? What can I consider as improvements in this concept?
I'm planning to create separate microservice and move all the database operations into it
That's how you will lose all benefits from microservice architecture. One service is down — the whole application is down. Unless you have replication on several nodes.
If your app does not work if one service went down(not implying that it's that service that connects to database), then it's still bad architecture and you are not using benefits of microservice architecture.
Correct for of communication would be if service would have their own databases. Or at least that every service that wants, for example, entity User, will not fetch it from DB, but will fetch it from appropriate service. And that appropriate service could fetch it from common DB at the beginning.
Next step (improvement) in the process of accommodation to microservice architecture would be creation of separate databases for each service. And by “separate” I mean that temporal fault of one service or temporal fault of one database will allow the rest of the app to be alive and functioning.
Generally, there are no hidden challenges in your approach. It just does not give any benefits, as an intermediate form between monolith application and microservice-based.

Does Serverless Framework support any kind of multi-cloud load balancing?

Does Serverless Framework support the ability to deploy the same API to multiple cloud providers (AWS, Azure and IBM) and route requests to each provider based on traditional load balancer methods (i.e. round robin or latency)?
Does Serverless Framework support this function directly?
Does Serverless integrate with global load balancers (e.g. dyn or neustar)?
Does Serverless Framework support the ability to deploy the same API to multiple cloud providers (AWS, Azure and IBM)
Just use 3 different serverless.yml files and deploy each function 3 times.
and route requests to each provider based on traditional load balancer methods (i.e. round robin or latency)?
No, there is no such support for multi-cloud load balancing
The Serverless concept is based on trust: you trust that your Cloud provider will be able to handle your traffic with proper scalability and availability. There is no multi-cloud model, a single Cloud provider must be able to satisfy your needs. To achieve this, they must implement a proper load-balacing schema internally.
If you don't trust on your Cloud provider, you are not thinking in a serverless way. Serverless means that you should not worry about the infra the supports your app.
However, you can implement a sort of multi-cloud load balancing
When you specify a serverless.yml file, you must say which provider (AWS, Azure, IBM) will create those resources. Multi-cloud means that you need one serverless.yml file per each Cloud, but the source code (functions) can be the same. When you deploy the same function to 3 different providers, you will receive 3 different endpoints to access them.
Now, which machine will execute the Load Balance? If you don't trust that a single Cloud provides enough availability, how will you define who will serve the Load Balance feature?
The only solution that I see is to implement this load-balacing in your frontend code. Your app would know the 3 different endpoints and randomize the requests. If one request returns an error, the endpoint would be marked as unhealthy. You could also determine the latency for each endpoint and select a preferred provider. All of this in the client code.
However, don't follow this path. Choose just one provider for production code. The SLA (service level agreement) usually provides a high availability. If it's not enough, you should still stick with just one provider and have in hand some scripts to easily migrate to another cloud in case of a mass outage of your preferred provider.

How do you develop a microservice in isolation when it depends on other microservices?

We are evaluating a move to microservices. Each microservice would be its own project developed in isolation. During planning, we have determined that some of the microservices will communicate with other via REST calls, pub/sub, messaging (ie. a order service needs product information from product service).
If a microservice depends on retrieving data from another microservice, how can it be run in isolation during development? For example, what happens when your order service requests product details, but there is nothing to answer that request?
What you probably need is an stub rest service. Create a webapp that takes the expected output using a path that is not part of the public api. When you invoke the public api it sends what it just received
If a microservice depends on retrieving data from another microservice, how can it be run in isolation during development?
It should be always temporally isolated from other services during development and production as well.
For example, what happens when your order service requests product details, but there is nothing to answer that request?
This is a place where design flaw reveals itself: order service should not request product details from another service. Product details should be stored in the message (event) that order service will be subscribed to. Order service should be getting this message in an asynchronous manner using publish-subscribe pattern and saving it in its own database. Data about the product will be stored in 2 places as the result of that.
Please consider reading this series of articles about microservices for more details. But in a nutshell: your services should be temporally decoupled, so when your product service is down - order service can continue its operations without interruptions. This is the key thing to understand about good distributed systems design in general.

Resources