Rust GraphQL demo/test API written in Rust, using Axum for routing, async-graphql and SQLx.
APIs are minimal and represent a blog site back-end, with GraphQL queries to create and delete draft posts, as well as, publish them.
The app includes tracing, using OpenTelemetry, with data pushed to a Jaeger Collector using the OpenTelemetry Protocol (OTLP). Metrics are also included, using Prometheus.
Based on How to Build a Powerful GraphQL API with Rust by Oliver Jumpertz, updated to use Axum 0.7 and generate an OTLP tracing stream, instead of the Jaeger HTTP format (Jaeger collector is still kept).
-
Clone this repo and change into the new directory.
-
Start the observability services with docker-compose:
docker compose up -d
-
Start the app with
cargo run
. The app will create the SQLite database file and run database migrations in themigrations
directory. -
Open a browser window at
http://localhost:8000
to bring up the GraphQL Playground and run some queries. -
The observability services might take a few moments to spin up, and in this case you will see Terminal output:
OpenTelemetry trace error occurred. Exporter otlp encountered the following error(s): the grpc server returns error (The service is currently unavailable): , detailed error message: tcp connect error: Connection refused (os error 61)
This should be temporary.
- Hello world:
query HelloQuery {
hello
}
- Create a draft:
mutation CreateDraftMutation {
createDraft(title: "Post working title", body: "Draft body text") {
id
title
}
}
- Delete a draft:
mutation DeleteDraftMutation {
deleteDraft(id: 1) {
__typename
... on DeleteDraftSuccessResponse {
post {
id
title
}
}
... on DeleteDraftErrorResponse {
error {
field
message
received
}
}
}
}
- List existing drafts:
query DraftsQuery {
drafts {
id
title
}
}
GraphQL Playground: http://localhost:8000/
Metrics raw output: http://localhost:8001/metrics
Jaeger Query UI: http://localhost:16686/search
The tracing service is provided via a Jaeger Collector, Jaeger Query UI and a Cassandra database, all running in Docker, and configured in docker-compose.yml
. The jaeger-all-in-one image has now been deprecated, as well as jaeger-agent
. jaeger-all-in-one
supported in-memory storage, and this is not supported by jaeger-collector
. Instead, you need to create a Cassandra (or Elasticsearch) database to store traces.
The API uses an SQLite single-file database for simplicity, at sqlite.db
. This is automatically created (if it does not yet exist) when the app spins up.
The repo is just intended as a reference to speed up creating am Axum-based GraphQL API with observability features.
- A production ready app
- Guide to using Axum, async-graphql or SQLx that covers every feature.
- To learn more about async-graphql, see:
- Axum also has great resource, including:
- axum docs; and
- axum examples.
- For SQLx resources, see:
- For a general introduction to building an web-based API in Rust, Zero to Production in Rust is marvellous.
Feel free to jump into the Rodney Lab matrix chat room.