prisma / prisma-examples

πŸš€ Ready-to-run Prisma example projects
https://www.prisma.io/docs/
Apache License 2.0
6.14k stars 1.43k forks source link

Add example for GraphQL-based microservices #322

Open jferrettiboke opened 6 years ago

jferrettiboke commented 6 years ago

I would love to see an example implementing GraphQL-based microservices with different databases and of course using an API gateway as the main entry point for client apps.

I suggest to add it into the official documentation or host it on "examples" folder in this repository.

marktani commented 6 years ago

Thanks @jferrettiboke, I agree that this would be an excellent example! If anyone is interested in contributing this, I can point you into the right direction. You can find me in our Slack, my handle there is @nilan.

ryannealmes commented 6 years ago

I have been trying to figure this out for a couple of days. I have managed to spin up some stuff and looking to introduce a schema stitched api to tie everything together, but getting everything to run off a single docker-compose file is proving to be impossible :/

jferrettiboke commented 6 years ago

Hi @ryannealmes!

I already planned some things but I didn't have enough time to play with the code. Anyway, we can discuss here things in more detail so that we can figure out the best option and you can play with the code and give me know your feelings about it.

I think, a better approach would be to have different projects running independently of others and expose each service with a programmatically API with GraphQL Binding library. Note that services will be consumed from the API gateway and they will not be exposed to the client. I think this is a better approach than use schema stitching.

I will give a quick example. Let's say we have to build a simple app for movies. So, we will need a Movie service. We will also have an API gateway which will be exposed to our client apps (web app, iOS app, Android app...). So, this will be another different project which will use the previous service. How can we connect with the service? You can make a simple network request with Axios (or another similar library) to the GraphQL API of the service or you can use GraphQL Binding library as I mentioned earlier (see oficial documentation for more details) to request data in a more elegant manner. You will be able to consume the services on your API gateway project like as follows:

// resolvers.js

const movieService = new MovieServiceBinding()

async function movie(parent, args, ctx, info) {
  return await movieService.movie({ id: args.id }, info);
}

I hope my comment can be helpful. Let me know whatever, I am very interested on this topic, so we could go further with a more real and complex example.

ryannealmes commented 6 years ago

Hey guys, I have really been enjoying working on a little pet project around this. It still needs lots of work, but I thought I would share it incase guys had comments that may benefit the exercise. Feel free to ping me on prisma slack (@ryannealmes) if you want to chat.

https://github.com/ryannealmes/shakra

I have managed to get auth/user service + goal service as 2 microservices stitched together and you can auth through the stitched api and pull anything you need. Also inter-service communication is handled prisma bindings ... so cool! @jferrettiboke I know you wanted to look at something without schema stitching, but I just couldn't resist ... it's too cool!

I want to go on to add a react front end and react native mobile app, devops and lots more. Also documentation probably has mistakes, but I will set it up on another PC just to make sure people can get started. Log issues if you find anything. Anyway feel free to tear it to shreds as well ... help me learn :)

aqwert commented 6 years ago

In case this helps, I put together a little guide (still rough around the edges) to create a graphql microservice implementation, with the GraphQLServer (yoga) being hosted as a Lambda. Each microservice is "stitched" together to form a single BFF Service. https://gist.github.com/aqwert/6a041827d24ebec3275f75a910018e3f

And a diagram: https://github.com/aqwert/code_architecture_design/blob/master/client_graphql_microservices.md

ryannealmes commented 6 years ago

Hey guys I have made quite a bit of traction on this - auth/user service, goal service, gateway service to combine the schemas, dB services leverage prisma and I also do ssr rendering with nextjs. Still a way to go but it’s getting there πŸ˜€

Check it out and let me know what you think

https://github.com/ryannealmes/shakra

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

jferrettiboke commented 5 years ago

I created a repository. Note how the example is using the shared database approach with no joins. Once Prisma supports multi-database, I think we could manage services easier with the same Prisma server at different databases.

Please, let me know guys what you think. Together, we can bring the best approaches and examples to the table.

otrebu commented 5 years ago

Hi @schickling @marktani! Do you know if anyone is working on completing this example?

dohaicuong commented 5 years ago

Apparently, Apollo release their new tools to build API gateway and microservices. I create a repository putting Apollo Federation and Prisma together. https://github.com/dohaicuong/prisma-microservices

jferrettiboke commented 5 years ago

@dohaicuong Thanks for sharing this.

One thing concerns me, though. How can Prisma ensure distributed transactions when using microservices? We should have events or something to communicate with other services.

dohaicuong commented 5 years ago

Sorry for the late reply.

That's what I've been looking at. So I could say event driven is a good approach in this case, or something like Saga to ensure the distributed transactions would make sense. However, I think there is no silver bullet for distributed system like this.

Or we can see if there any supports from prisma team about the good approach for this maybe :))