this

GraphQL Microservice Example

This example demonstrates the use of GraphQL exposure in the this-rs framework alongside the REST API.

🎯 Features

Getting Started

cargo run --example microservice_graphql --features graphql

The server starts on http://127.0.0.1:3000 with both REST and GraphQL endpoints.

Available Endpoints

GraphQL Playground

Access the interactive playground: http://127.0.0.1:3000/graphql/playground

GraphQL Schema

Download the SDL schema: http://127.0.0.1:3000/graphql/schema

The schema is automatically generated from registered entities:

The SDL (Schema Definition Language) is useful for:

Available GraphQL Queries

List entities with pagination

query {
  orders(limit: 10, offset: 0) {
    id
    number
    customerName
    amount
    status
    invoices {
      id
      number
      amount
    }
  }
}

Get entity by ID

Instead of using entity(id, entityType), you can query directly by type:

query {
  order(id: "UUID") {
    id
    number
    customerName
    amount
    status
    createdAt
    updatedAt
  }
}

Automatic relations

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"
            }
          ]
        }
      ]
    }
  }
}

Available GraphQL Mutations

Create entity

mutation {
  createOrder(data: {
    number: "ORD-001"
    customerName: "John Doe"
    amount: 1000.0
    status: "active"
    notes: "First order"
  }) {
    id
    number
    customerName
    amount
    status
  }
}

Update entity

mutation {
  updateOrder(
    id: "UUID"
    data: {
      amount: 1500.0
      status: "completed"
    }
  ) {
    id
    amount
    status
  }
}

Delete entity

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.

Examples with curl

Get the SDL schema

curl http://127.0.0.1:3000/graphql/schema

Returns the complete schema in SDL format, including all available types, queries, and mutations.

List orders

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 order with relations

# 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 } } } }\"}"

Get an invoice with payments

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 } } }\"}"

Create an order

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 } }\"}"

Architecture

This example combines two framework exposures:

  1. REST Exposure (RestExposure): Provides the classic REST API
  2. GraphQL Exposure (GraphQLExposure): Provides the GraphQL API

Both exposures share the same ServerHost, which contains:

Technical Notes

✅ Implemented Features

Current Limitations

Next Steps