= GraphQL applications :nav-title: GraphQL :description: Give your app a GraphQL endpoint over your collections without writing resolvers: a schema, a mapping from types to collections, and the endpoint is live. :keywords: GraphQL API, GraphQL backend, MongoDB GraphQL, GraphQL without resolvers, GraphQL endpoint for React :group: Build :order: 10 A GraphQL app is a schema and a mapping. The schema says which types and queries your app can ask for; the mapping says which collection answers each one. Save it under **GraphQL** and the endpoint is live at `/graphql/`, with no resolver code. A service can host several apps, each with its own schema and address. image::/assets/docs-images/graphql.png[The GraphQL page: the apps of the service, and New App] == An app in one document [source,json] ---- { "descriptor": { "name": "Shop", "description": "The shop's read API", "enabled": true, "uri": "shop" }, "schema": "type Query { orders(status: String): [Order] } type Order { _id: String status: String total: Float customer: User } type User { _id: String name: String }", "mappings": { "Query": { "orders": { "db": "restheart", "collection": "orders", "find": { "status": { "$arg": "status" } } } }, "Order": { "customer": { "db": "restheart", "collection": "users", "find": { "_id": { "$fk": "customerId" } } } } } } ---- * **descriptor**: the name, the `uri` the endpoint is served at, and `enabled`, which takes the app offline without deleting it. * **schema**: the GraphQL SDL, as a string. Types, queries, and mutations if you want them. * **mappings**: for each type, how each field is resolved. A root field names a `db` and a `collection` and optionally `find`, `sort`, `limit` and `skip`. `$arg` puts a query argument into the filter, so `orders(status: "pending")` becomes `find({status: "pending"})`. `$fk` takes a value from the parent document, which is how `Order.customer` looks up the user: a join, declared in one line. On Free and Shared the database is `restheart`. On Dedicated, name the one you use. == Create one Click **New App**. The **Visual Editor** gives you a field for each part; the **JSON Editor** takes the whole document, which is handy when pasting one from git. Both check what you type, and **Format** tidies the JSON. **Save**, and the endpoint answers. Changes take effect at once. Each app in the list has an enable switch, **Edit**, **Delete**, and **Copy URL** for the endpoint address. == Call it from your app [source,javascript] ---- const res = await fetch('https://f3a9c1.eu-central-1-free-1.restheart.com/graphql/shop', { method: 'POST', headers: { 'Authorization': 'Basic ' + btoa('alice:secret'), 'Content-Type': 'application/json' }, body: JSON.stringify({ query: 'query Orders($status: String) { orders(status: $status) { _id total customer { name } } }', variables: { status: 'pending' } }) }); const { data } = await res.json(); ---- The user needs a xref:managing-permissions.adoc[permission] on `/graphql/shop`. Any GraphQL client works: paste the URL from **Copy URL** into it. == From a script Apps are documents in the `gql-apps` collection, `/restheart/gql-apps` on Dedicated: [cols="2,3"] |=== | Operation | API | List | `GET /gql-apps` | Create | `POST /gql-apps` with the app document | Update | `PATCH /gql-apps/` | Delete | `DELETE /gql-apps/` | Query | `POST /graphql/` |=== With xref:cli.adoc[`rhc`], apps are part of the setup file. The full mapping language, with mutations, aggregations as resolvers and batching, is in the link:{restheart-docs}/mongodb-graphql/getting-started[GraphQL reference]. == Related pages * xref:managing-data.adoc[Collections and documents]: the data the apps resolve against. * xref:mcp.adoc[MCP server]: a GraphQL app you publish is one an AI agent can query too. * xref:managing-permissions.adoc[Permissions]: who may query which app.