Effect RPC provides a bridge architecture that compiles annotated RPC groups into GraphQL schemas, allowing developers to serve GraphQL APIs using the same implementations and contracts as RPC routes, eliminating the need to create a GraphQL server from scratch while maintaining type safety and leveraging effect's built-in features like codecs, middleware, and live implementations.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
Effect.ts + GraphQL | Using Effect RPC to Serve GraphQL
Added:Now, before I start the video, if you want to learn all about effect, make sure to check out the description. I have two courses, one titled effect, which for now is on V3. And once V4 is out, you will get the update in roughly 3 months, and an effect atom course. And this one is already in V4. But do not worry about V3 or V4. Fundamentally, they are the same thing. Plus, we're using AI to write all of our code. So, what you need is to understand the fundamentals and the mental model so that you can guide your AI. Anyway, make sure to check out the link in the description. Okay. So, let's take a look at how we can serve a GraphQL API using effect. For this, I'll be relying entirely on effect RPC. And the reason for that is effect RPC gives us everything we need to integrate our effect code meaning the codecs so the schemas for success error payloads etc the middleares the live implementation for the layers etc. So there is no reason to create from scratch a graphql server all in effect. All we need to do is take an effect RPC contract and translate that over to GraphQL. So compile that contract into GraphQL and then serve a route that serves the GraphQL API. And this gives us many benefits. Of course, one of them being what I already mentioned. It is already in effect using the official effect conventions. But most importantly, you can serve an effect RPC route and a GraphQL route using the same implementations and the same contracts.
So if you want to use RPC in your private monor repo, you can still do that without refactoring your code. And in parallel, you can serve a GraphQL API that again relies on the same RPC contract. Now this example targets effect v4 and we will be using the base graphql package for everything. So the bridge compiles an annotated RPC group into a graphql schema. And as we can see here in the rhymi payload codecs result codeex middleware handler layers typed failures defects headers streams and cancellation follow the RPC path instead of bypassing it. So in other words, we get all of the RPC goodies. Now this repository is a design example. This is not a published mpm package. And you will see that I'm not implementing GraphQL through a custom RPCC realization or protocol layer. And that's because GraphQL needs to parse validate the document, select the fields, coers the variables, execute the resolvers, etc. So we need an abstraction that sits higher up. Now you can find the repository in the description. So here I have a complete example under the example directory and you can test it out with pmppm example.
And what this is going to do is replicate a real consumer in that it is going to well start the HTTP server which is going to serve the GraphQL API.
Then it is going to introspect the GraphQL endpoint. Then generates the TypeScript code from it. Then run an Apollo client, print the responses, and then for cleanup purposes removes the database when it finishes. And if you want to keep the server running, you can use PMP example server. Anyway, let's take a look at the API or rather the developer experience. So here as we can see we define the contract. So we say user ID then number from string then we branded for a nominal type. But notice how we use graphql ID. And this is just so that it works with the GraphQL ID color. Then we have the user and then here we name it. So we say this will be an object type user. And then for CAD user we use RPC.make.
And then here we define the payload success and error. And then we pipe through this and say graphql.query.
And then we say field user and then the description. So in a way pretty much the same thing as defining your graphql schema but of course you do it through the RPC annotations and then we say RPC group. Make for a get user. But here you would merge the different RPC groups that you have and so on including well of course middleware. Now for serving it what you do is say HTTP router.serve and then notice how we serve too. We serve the GraphQL server. So we pass in the group and then the path and then RPC server layer HTTP. So again we can serve both an RPC route and a GraphQL route.
So very similar API wise and then we provide the live implementations. Now for the annotation API this will not affect how you can use these schemas. So even though for the user ID we are using graphql ID and then for the user entity graphql.object type you can still use the schema to decode and code whatever you want. It is just an internal annotation so that the compiler can look for that information.
So let's quickly understand the concepts. So we have GraphQL object type and this names and output object. So if you have a mutation in GraphQL then the return type of that will be the object type that you define and then you have the input object type for the input what the server will receive. and well validate. So for this right here we would have the input coordinates input and then the fields here and then for the object type let's say we have create and then input will be coordinates input and this will be required and then for the result type we have coordinates something like this if I'm not mistaken.
So this is a way for you to attach that to a schema so that the compiler can generate these types. So in this case for coordinates we're saying that this right here will be of object type coordinates and then we also create an input type called coordinates input. Now graphql ID again this is for the graphql ID scalar. So as we can see a plain string codec would otherwise compile to graphql string. So graphql ID says that the value has identity semantics and should compile to the graphql ID color scholar instead. So this right here with a graphql ID will produce this. So pretty straightforward. Then again for the object types input and enums. So we can say schema. and then pipe through this and say graphql.inum type and as we can see we get this right here in the final schema. And now for the root fields we have graphql.query graphql.mutation and graphql.subscription.
So here we have get task and we have the payload success and error. We pipe through this. We say graphql.query then field task and then the description. And this is going to generate this right here. So a type query with the task method or procedure and same for mutations. So we can say build create task and then the arguments and this will use the payload. So as we can see create task receives the create task input and then we define the properties and for graphql.subscription subscription. All you need to do is say stream true and this will be handled as a graphql subscription. So as we can see graphql.subscription requires a streaming RPC. Then we also have graphql.field.
So we can say display name schema string I then graphical field and then for the name we can say this will be name and then the description and then the object type. So notice how we're doing a rename. So from display name to name and the compiler will take care of that for us. Then you can also use graphql.hidden output. So for example an encoded implementation field that graphql needs at runtime but clients should not see in output object. So for example we can create tagged unions and not expose the tag in the SDL. We have the graphql scholar. So we can for example create a graphql datetime and we have union types. We have nullability and partial selection where you can use schema optional key and the schema null or and that's pretty much it. And here I have a table describing the behavior. So a schema string will be a string in GraphQL. a graphql ID will be an ID and so on and so forth. So let's take a look at the root under example. So here we have RPC live which is just an RPC server layer HTTP. We pass in the RPC group then the path and protocol and then we have the app live which is just graphq server.serve serve and then same thing group API and then the path and finally we provide all of the implementations it needs. So RPC live again so we can serve an RPC route the API live implementation the database live and then the serialization strategy for RPC live and then we create the server and launch it using the node runtime. Now let's take a look at this group. So as we can see we have our entity ids all using graphql id. Then we have enoms using graphql enum type. Then the entities using object type. Then we have a task filter which is an input object type. And notice how it is nullable and optional. And then we have create task input move task input etc. And finally we reach the RPCs where we say query and we have some mutations here and I believe we have a subscription here as we can see where we use stream and then we can say graphqlsubscription and then here we just export the API saying RPCG groupoup.make we pass in all of the procedures and we also use the O middleware and then for API live so the implementation of the API for the server. We have this task change service which is just a popsub. We have the O live so succeed for the O middleware with this hardcoded handler. Then we have API live which is going to yield the repository and the changes service and then we handle the controller stuff and finally we say API.layer and that's it. So again pretty straightforward. This is just effect RPC after all. And then here we have a demo.ts file where we create an Apollo client and we also generate the code. As we can see we got generated graphql.ts and then we can say awaitclient.query and then we pass in the autogenerated document and we get the type safety and all. And if you want to consume the RPC1 instead, then you would use the effect RPC client and consume the contract and provide the protocol and the serialization strategies. And as for generated again, we get all of the type safety. So if you want to play around, understand how it works, make sure to check out the repository in the description. Here under source, you'll find the GraphQL library. So you can check out how the compiler and everything works internally. Anyway, that's it for this video. If you want to see more content like this, make sure to subscribe. I'll see you in the next one.
to you.
Related Videos

TOP 15 Data compression Interview Questions and Answers 2019 Part-2 | Data compression | Wisdom jobs
wisdomjobs
281 views•2019-06-28

CTS 158: 802.11w Management Frame Protection
ClearToSend
4K views•2019-02-04

NDSS 2019 Send Hardest Problems My Way: Probabilistic Path Prioritization for Hybrid Fuzzing
NDSSSymposium
496 views•2019-04-02

How realistic is Cities: Skylines?
CityBeautiful
159K views•2019-02-14

GUIs & TUIs: Choosing a User Interface for Your Python Project | Real Python Podcast
realpython
2K views•2025-04-04

The OSI Model - Explained by Example
hnasr
225K views•2019-05-12

Cloud Computing - Introduction
elithecomputerguy
98K views•2019-10-07

From Traveler's Dilemma to Dynamic Routing | Demystifying Networking
IITBombayJuly
5K views•2019-08-04
Trending

Ben Crump dealt MAJOR BLOW after His Own Nolan Wells Autopsy FACT CHECKS him
DeVoryDarkins
50K views•2026-07-23

Gremlin Arrives… While Dorothy May Takes Another Step Forward
The-moons
10K views•2026-07-23

Trump War Chief SCREWS UP by Posting Video Leading Judge to ORDER an EXPLANATION!!!
LegalAFMTN
110K views•2026-07-23

Playstation NO DISC/NO BUY Fight Is Over...
DavidJaffeGames
4K views•2026-07-23