This example demonstrates the use of GraphQL exposure in the this-rs framework alongside the REST API.
order(id), invoice(id), payment(id)orders, invoices, payments with pagination supportorder.invoices, invoice.payments)order.invoices.payments)cargo run --example microservice_graphql --features graphql
The server starts on http://127.0.0.1:3000 with both REST and GraphQL endpoints.
/graphql (POST)/graphql/playground (GET)/graphql/schema (GET)Access the interactive playground: http://127.0.0.1:3000/graphql/playground
Download the SDL schema: http://127.0.0.1:3000/graphql/schema
The schema is automatically generated from registered entities:
Order, Invoice, Payment)links.yamlThe SDL (Schema Definition Language) is useful for:
query {
orders(limit: 10, offset: 0) {
id
number
customerName
amount
status
invoices {
id
number
amount
}
}
}
Instead of using entity(id, entityType), you can query directly by type:
query {
order(id: "UUID") {
id
number
customerName
amount
status
createdAt
updatedAt
}
}
Entities automatically expose their relations via fields:
query {
order(id: "UUID") {
id
number
customerName
invoices {
id
number
amount
dueDate
payments {
id
amount
method
transactionId
}
}
}
}
Result:
{
"data": {
"order": {
"id": "d16e72cf-d7f7-41f4-aa86-ca428967fa0a",
"number": "ORD-001",
"invoices": [
{
"id": "b5ef6156-0dcb-49fd-b425-5805044ddbc4",
"number": "INV-002",
"payments": [
{
"id": "90164a77-d517-4c27-8677-ac56a665cb9c",
"amount": 500.0,
"method": "credit_card"
}
]
}
]
}
}
}
mutation {
createOrder(data: {
number: "ORD-001"
customerName: "John Doe"
amount: 1000.0
status: "active"
notes: "First order"
}) {
id
number
customerName
amount
status
}
}
mutation {
updateOrder(
id: "UUID"
data: {
amount: 1500.0
status: "completed"
}
) {
id
amount
status
}
}
mutation {
deleteOrder(id: "UUID")
}
Returns true if deleted successfully, false otherwise.
Create a new entity and automatically link it to a parent:
mutation {
createInvoiceForOrder(
parentId: "ORDER_UUID"
data: {
number: "INV-001"
amount: 500.0
status: "pending"
dueDate: "2024-12-31"
}
) {
id
number
amount
order {
id
number
}
}
}
Link two existing entities together:
mutation {
linkPaymentToInvoice(
sourceId: "PAYMENT_UUID"
targetId: "INVOICE_UUID"
linkType: "payment"
metadata: {
processed: true
timestamp: "2024-01-15T10:30:00Z"
}
) {
id
linkType
sourceId
targetId
metadata
}
}
Remove a link between two entities:
mutation {
unlinkPaymentFromInvoice(
sourceId: "PAYMENT_UUID"
targetId: "INVOICE_UUID"
)
}
mutation {
createLink(
sourceId: "UUID"
targetId: "UUID"
linkType: "has_invoice"
metadata: {note: "Test link", priority: "high"}
) {
id
linkType
sourceId
targetId
metadata
createdAt
}
}
Without metadata:
mutation {
createLink(
sourceId: "UUID"
targetId: "UUID"
linkType: "has_invoice"
) {
id
linkType
}
}
mutation {
deleteLink(id: "UUID")
}
Returns true if deleted, false otherwise.
curl http://127.0.0.1:3000/graphql/schema
Returns the complete schema in SDL format, including all available types, queries, and mutations.
curl -X POST http://127.0.0.1:3000/graphql \
-H "Content-Type: application/json" \
-d '{"query": "query { orders(limit: 5) { id number customerName amount } }"}'
# Get an ID from REST
ORDER_ID=$(curl -s http://127.0.0.1:3000/orders | jq -r '.data[0].id')
# GraphQL query with relations
curl -X POST http://127.0.0.1:3000/graphql \
-H "Content-Type: application/json" \
-d "{\"query\": \"query { order(id: \\\"$ORDER_ID\\\") { id number customerName invoices { id number amount payments { id amount method } } } }\"}"
INVOICE_ID=$(curl -s http://127.0.0.1:3000/invoices | jq -r '.data[0].id')
curl -X POST http://127.0.0.1:3000/graphql \
-H "Content-Type: application/json" \
-d "{\"query\": \"query { invoice(id: \\\"$INVOICE_ID\\\") { id number amount payments { id amount method } } }\"}"
curl -X POST http://127.0.0.1:3000/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "mutation { createOrder(data: { number: \"ORD-999\", customerName: \"Jane Doe\", amount: 2000.0, status: \"active\", notes: \"Test order\" }) { id number customerName amount } }"
}'
ORDER_ID=$(curl -s http://127.0.0.1:3000/orders | jq -r '.data[0].id')
curl -X POST http://127.0.0.1:3000/graphql \
-H "Content-Type: application/json" \
-d "{\"query\": \"mutation { createInvoiceForOrder(parentId: \\\"$ORDER_ID\\\", data: { number: \\\"INV-999\\\", amount: 1500.0, status: \\\"pending\\\", dueDate: \\\"2024-12-31\\\" }) { id number amount } }\"}"
ORDER_ID=$(curl -s http://127.0.0.1:3000/orders | jq -r '.data[0].id')
INVOICE_ID=$(curl -s http://127.0.0.1:3000/invoices | jq -r '.data[0].id')
curl -X POST http://127.0.0.1:3000/graphql \
-H "Content-Type: application/json" \
-d "{\"query\": \"mutation { createLink(sourceId: \\\"$ORDER_ID\\\", targetId: \\\"$INVOICE_ID\\\", linkType: \\\"has_invoice\\\") { id linkType } }\"}"
This example combines two framework exposures:
RestExposure): Provides the classic REST APIGraphQLExposure): Provides the GraphQL APIBoth exposures share the same ServerHost, which contains:
Order, Invoice, Payment) - not genericlinks.yaml configurationorder, invoice, payment)orders, invoices, payments)createOrder, updateOrder, deleteOrder)createInvoiceForOrder, linkPaymentToInvoice)createLink and deleteLink mutations/graphql/schema@deprecated, @skip, etc.)