Rust microservices with Typescript SvelteKit using gRPC deployed on Fly.io
If You have any questions, feel free to ask them in Discussions or Issues. I hope this will be helpful :).
For now this project will be the one that i will try to keep up to date and update it with new functionalities. SvelteKit + Rust is an perfect combo for me now :)
Check out my other, similar projects if You need it:
Demo
https://rust-grpc-client.fly.dev/
Architecture
- Rust as microservices
- SvelteKit client for frontend
- SvelteKit server for gateway and page protection
- Gateway to services and service to service communication using gRPC
- Authorization between Svelte client and server using AuthJS
- Authorization between services using local JWT tokens for maximum performance
- So yeah, everything works on gRPC, either as stream or unary, IT IS FAST, locally request can be as fast as 3-10 ms
- Deployed on Fly.io as docker containers (previously deployed on GCP, but they require authorization using http api, which slows down request, fly.io is much faster with pure gRPC + JWT tokens)
Features
- Data fetching using gRPC streams. Inserting / updating / deleting using unary.
- The same Protocol Buffers are used by both Rust and Typescript services, which means that the types are shared! Amazing end-to-end typesafety.
- Using proto enums to ensure consistency between frontend / backend.
- Rust sql connection using pools spread throught the service.
- Sqlx transactions, which means that no database entry will be saved when an error occur.
- Each Rust error is mapped and safetly returned.
Three ways to shows notes
This project shows how flexible the gRPC + SvelteKit setup is, using the newest SvelteKit streamed
feature. There are three ways to display notes:
svelte server
callsnotes service
->notes service
selects all notes -> for each note it callsusers service
for user -> the note with the user is returned as streamsvelte server
callsnotes service
->notes service
selects all notes and return them -> for each notesvelte server
callsusers service
for user -> not waiting for users to resolve, he dispaly the notes, and after that await users asstreamed
datasvelte server
callsnotes service
->notes service
selects all notes and return them -> for each notesvelte server
add userId to set -> then, in one request he callsusers service
for all users -> not waiting for users to resolve, he displays notes and after that await users asstreamed
data
Try to create hundres of notes and You will see the diffrence :)
- Files send as bytes, on development environment they are stored in /files folder, on production environment in Fly.io volumes. Client send base64 string to Node server using SvelteKit api, which then creates a file and respond with a download header.
Dev deployment
- Client setup:
cp client/.env.dist client/.env
npm i --prefix client
- Fill in missing secrets in
client/.env
:
- JWT_SECRET
- GOOGLE_ID
- GOOGLE_SECRET
- AUTH_SECRET
If You don't need paswordless auth, delete the adapter and Email provider in hooks.server.ts
. If You need them, then You also must fill this secrets:
- SENDGRID_API_KEY
- REDIS_URL
- REDIS_TOKEN
- Start docker:
docker-compose up --build
Proto generation
# ./client
npm run proto
# ./service-******
cargo run --bin proto