Yes, I know that this is a borderline absurd web stack for the ubiquitous TODO application but I had a lot of trouble getting this all to work. I started using these things for a more ambitious project and I'd love to spare you the trouble. So here's some basic boilerplate to get you up and running.
Here's what does what:
| Component | Tool/lib |
|---|---|
| Web server | actix-web |
| Database | PostgreSQL |
| SQL engine | Diesel |
| GraphQL library | Juniper |
| GraphQL UI | GraphQL Playground |
Before you get started, make sure that you have PostgreSQL, Rust, Cargo, and the Diesel CLI installed and that you have Postgres running somewhere.
# Fetch the repo git clone https://github.com/lucperkins/rust-actix-diesel-postgres-juniper cd rust-actix-diesel-postgres-juniper # If you would like to run the postgres server in docker docker compose up # Set up the database cp .env.example .env # Modify this file to match your Postgres installation diesel setup diesel migration run cargo run # could take a while!
The
DATABASE_URLcan be any Postgres installation. For my purposes, I have it set topostgres://localhost:5432/todos.
Once the server is running, you can access the GraphQL Playground UI at http://localhost:4000/graphql.
The server implements the following GraphQL schema:
type Todo { id: ID! task: String! done: Boolean! } input CreateTodoInput { task: String! done: Boolean } type Query { allTodos: [Todo!]! getTodoById(id: Int): Todo } type Mutation { createTodo(input: CreateTodoInput): Todo markTodoAsDone(id: Int): Todo markTodoAsNotDone(id: Int): Todo } schema { Query Mutation }
| File | What it provides |
|---|---|
context.rs |
The GraphQL context that handles query execution |
data.rs |
A Todos struct and some helper functions encapsulate the Diesel-powered Postgres querying logic |
db.rs |
The connection pool that handles the Postgres connection |
endpoints.rs |
The /graphql HTTP endpoint that makes GraphQL and the GraphQL Playground work |
graphql.rs |
The Query, Mutation, and Schema objects that undergird the GraphQL interface |
lib.rs |
Just the standard lib.rs |
main.rs |
Actix HTTP server setup |
models.rs |
All of the data types used for querying Postgres and providing GraphQL results |
schema.rs |
The Diesel-generated table schema |
Get it? Anyway, here's some areas for improvement (pull requests very much welcome):
juniper_from_schema macro could help reduce boilerplate and improve development velocity.I'm basically a beginner with Rust and would not have been able to put this together without peeking long and hard at the example projects and blog posts listed below. The lower-level bits you see here are basically stolen from BrendanBall. All that I've added is the Todos data construct for executing queries.