GraphQL vs REST
GraphQL vs REST
Litmus uses both. Knowing which module is which prevents the most common 200-with-no-data confusion.
Which modules use which
Module | Protocol |
|---|---|
LE DeviceHub | GraphQL at /devicehub/v2 (most ops); a few REST endpoints for CSV upload/download and storage toggle |
LE Digital Twins | GraphQL at /digitaltwins/v2 |
LE Integration | GraphQL at /cc/v2 |
LE OPC UA | GraphQL at /opcua/v2 |
LE DataHub, Flows, Analytics, Applications, System, Auth | REST |
LEM (all modules) | REST |
LUNS (all modules) | GraphQL at /mqtt/gql |
GraphQL gotchas
1. Error envelope
GraphQL endpoints return HTTP 200 even on validation errors. The error sits in the body:
{
"data": null,
"errors": [
{ "message": "Driver not found", "path": ["CreateDevice"] }
]
}Your client must check body.errors, not just the HTTP status. Treat errors being a non-empty array as a failure.
2. Operation name is in the body
REST callers think in URLs. GraphQL callers think in operations. The URL stays the same; the query or mutation selects the action:
# Same URL, two different operations:
curl -X POST .../devicehub/v2 -d '{"query":"query { ListDriverGroups { ... } }"}'
curl -X POST .../devicehub/v2 -d '{"query":"mutation { CreateDevice(input: {...}) { ID } }"}'3. Field selection is required
You must explicitly name the fields you want back. Asking for everything in a single query is not idiomatic - request only what you'll read.
4. Pagination, filtering, sorting
These vary per operation. Most list operations accept an input argument with Limit, Offset, Filter, Sort fields. Check the operation's schema before assuming defaults.
REST conventions in Litmus
- Path-versioned: /devicehub/v2, /digitaltwins/v2, /dm/template/v2 - new major versions don't break old clients.
- Resumable uploads: DELETE -> POST {size} -> PUT {bytes} pattern. See Resumable Uploads.
- Async tasks (LEM): POST returns taskId, then GET /async-task/{id}/subtasks polls until SUCCESS.
- Standard HTTP status codes - 200/201 success, 400 validation, 401 auth, 403 forbidden, 404 missing, 5xx server.
How to spot GraphQL vs REST on the API portal
Browsing api.litmus.io:
- GraphQL requests show as POST with a JSON body containing query and optional variables.
- REST requests show varied HTTP methods and typed bodies.
- Look at the URL: anything ending in /v2 with no further path (/devicehub/v2, /cc/v2, /opcua/v2, /digitaltwins/v2, /mqtt/gql) is GraphQL.