<p>Appwrite supports multiple protocols for accessing the server, including <a href="/docs/rest">REST</a>, <a href="/docs/graphql">GraphQL</a>, and <a href="/docs/realtime">Realtime</a>.</p>

<p>The GraphQL API allows you to query and mutate any resource type on your Appwrite server through the endpoint <code>/v1/graphql</code>. Every endpoint available through REST is available through GraphQL, except for OAuth.</p>

<h2><a href="/docs/graphql#requests" id="requests">Requests</a></h2>

<p>Although every query executes through the same endpoint, there are multiple ways to make a GraphQL request. All requests, however, share a common structure.</p>

<table class="vertical full args">
    <thead>
    <tr>
        <td style="width: 140px">Name</td>
        <td style="width: 70px"></td>
        <td style="width: 120px">Type</td>
        <td>Description</td>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td data-title="Name: ">
            query
        </td>
        <td data-title="">
            <span class="tag red">required</span>
        </td>
        <td data-title="Type: ">
            string
        </td>
        <td data-title="Description: ">
            The GraphQL query to execute.
        </td>
    </tr>
    <tr>
        <td data-title="Name: ">
            operationName
        </td>
        <td data-title="">
            <span class="tag">optional</span>
        </td>
        <td data-title="Type: ">
            string
        </td>
        <td data-title="Description: ">
            If the query contains several named operations, controls which one to execute.
        </td>
    </tr>
    <tr>
        <td data-title="Name: ">
            variables
        </td>
        <td data-title="">
            <span class="tag">optional</span>
        </td>
        <td data-title="Type: ">
            object
        </td>
        <td data-title="Description: ">
            An object containing variable names and values for the query. Variables are made available to your query with the <code>$</code> prefix.
        </td>
    </tr>
    </tbody>
</table>

<div class="notice">
  <h2>GraphQL Model Parameters</h2>

  <p>In Appwrite's GraphQL API, all internal model parameters are prefixed with <code>_</code> instead of <code>$</code> because <code>$</code> is reserved by GraphQL.</p>

  <p>For example, <code>$collectionId</code> in the REST API would be referenced as <code>_collectionId</code> in the GraphQL API.</p>

</div>


<h3><a href="/docs/graphql#get-requests" id="get-requests">GET Requests</a></h3>

<p>You can execute a GraphQL query via a GET request, passing a <code>query</code> and optionally <code>operationName</code> and <code>variables</code> as query parameters.</p>

<h3><a href="/docs/graphql#post-requests" id="post-requests">POST Requests</a></h3>

<p>There are multiple ways to make a GraphQL POST request, differentiated by content type.</p>

<h4>JSON</h4>

<p>There are two ways to make requests with the <code>application/json</code> content type. You can send a JSON object containing a <code>query</code> and optionally <code>operationName</code> and <code>variables</code>, or an array of objects with the same structure.</p>

<ul class="phases clear" data-ui-phases>
    <li>
        <h3>Object</h3>
        <div class="ide margin-bottom" data-lang="json" data-lang-label="JSON">
            <pre class="line-numbers"><code class="prism language-json" data-prism>{
    "query": "",
    "operationName": "",
    "variables": {}
}</code></pre>
        </div>
    </li>
    <li>
        <h3>Array</h3>
        <div class="ide margin-bottom" data-lang="json" data-lang-label="JSON">
            <pre class="line-numbers"><code class="prism language-json" data-prism>[
    {
        "query": "",
        "operationName": "",
        "variables": {}
    }
]</code></pre>
        </div>
    </li>
</ul>

<h4>GraphQL</h4>

<p>The <code>application/graphql</code> content type can be used to send a query as the raw POST body.</p>

<div class="ide margin-bottom" data-lang="graphql" data-lang-label="GraphQL">
    <pre class="line-numbers"><code class="prism language-graphql" data-prism>query GetAccount {
    accountGet {
        _id
        email
    }
}</code></pre></div>

<h4>Multipart Form Data</h4>

<p>The <code>multipart/form-data</code> content type can be used to upload files via GraphQL. In this case, the form data must include the following parts in addition to the files to upload:</p>

<table class="vertical full args">
    <thead>
    <tr>
        <td style="width: 140px">Name</td>
        <td style="width: 70px"></td>
        <td style="width: 120px">Type</td>
        <td>Description</td>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td data-title="Name: ">
            operations
        </td>
        <td data-title="">
            <span class="tag red">required</span>
        </td>
        <td data-title="Type: ">
            string
        </td>
        <td data-title="Description: ">
            JSON encoded GraphQL query and optionally operation name and variables. File variables should contain null values.
        </td>
    </tr>
    <tr>
        <td data-title="Name: ">
            map
        </td>
        <td data-title="">
            <span class="tag red">required</span>
        </td>
        <td data-title="Type: ">
            string
        </td>
        <td data-title="Description: ">
            JSON encoded map of form-data filenames to the operations dot-path to inject the file to, e.g. <code>variables.file</code>.
        </td>
    </tr>
    </tbody>
</table>

<h2><a href="/docs/graphql#responses" id="responses">Responses</a></h2>

<p>A response to a GraphQL request will have the following structure:</p>

<table class="vertical full args">
    <thead>
    <tr>
        <td style="width: 140px">Name</td>
        <td style="width: 120px">Type</td>
        <td>Description</td>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td data-title="Name: ">
            data
        </td>
        <td data-title="Type: ">
            object
        </td>
        <td data-title="Description: ">
            The data returned by the query, maps requested field names to their results.
        </td>
    </tr>
    <tr>
        <td data-title="Name: ">
            errors
        </td>
        <td data-title="Type: ">
            object[]
        </td>
        <td data-title="Description: ">
            An array of errors that occurred during the request.
        </td>
    </tr>
    </tbody>
</table>

<p>The data object will contain a map of requested field names to their results. If no data is returned, the object will not be present in the response.</p>

<p>The errors array will contain error objects, each with their own <b>message</b> and <b>path</b>. The path will contain the field key that is null due to the error. If no errors occur, the array will not be present in the response.</p>

<h2><a href="/docs/realtime#authentication" id="authentication">Authentication</a></h2>
<p>GraphQL authenticates using Appwrite accounts and sessions. Both accounts and sessions can be created with GraphQL using the <code>accountCreate</code>, <code>accountCreateEmailSession</code>, <code>accountCreateAnonymousSession</code>, or <code>accountCreatePhoneSession</code> mutations.</p>

<p>More information and examples of authenticating users can be found in the dedicated <a href="/docs/authentication">authentication guide</a>.</p>

<h2><a href="/docs/graphql#graphql-vs-rest" id="graphql-vs-rest">GraphQL vs REST</a></h2>

<p>There are two main features that make GraphQL appealing when compared to the REST API: <b>selection sets</b> and <b>query batching.</b></p>

<h3><a href="/docs/graphql#selection-sets" id="selection-sets">Selection Sets</a></h3>

<p>Selection sets can be used to tell a GraphQL API exactly which fields of a particular resource you would like to receive in the response. The server will respond with only those fields, nothing more, nothing less. This gives you full control over what data comes into your application.</p>

<p>For example, to retrieve only the email of a currently authenticated user, you could query the <code>accountGet</code> field, passing only email as the <b>field selection set</b>.</p>

<div class="ide margin-bottom" data-lang="graphql" data-lang-label="GraphQL">
    <pre class="line-numbers"><code class="prism language-graphql" data-prism>query GetAccount {
    accountGet {
        _id
        email
    }
}</code></pre></div>

<p>Given this query, the GraphQL API will respond with:</p>

<div class="ide margin-bottom" data-lang="json" data-lang-label="JSON">
    <pre class="line-numbers"><code class="prism language-json" data-prism>{
    "data": {
        "accountGet": {
            "_id": "...",
            "email": "..."
        }
    }
}</code></pre></div>

<p>This can be a useful feature for performance, network efficiency, and app responsiveness. As the processing happens on the server, the bandwidth consumed for the request can be dramatically reduced.</p>

<h3><a href="/docs/graphql#query-batching" id="query-batching">Query Batching</a></h3>

<p>GraphQL allows sending multiple queries or mutations in the same request. There are two different ways to batch queries. The simplest way is to include multiple fields in a single query <b>or</b> mutation.</p>

<div class="ide margin-bottom" data-lang="graphql" data-lang-label="GraphQL">
    <pre class="line-numbers"><code class="prism language-graphql" data-prism>query GetAccountAndLocale {
    accountGet {
        _id
        email
    }
    localeGet {
        ip
    }
}</code></pre></div>

<p>If both field executions succeed, the response will contain a data key for each field, containing the values of the selected fields.</p>

<div class="ide margin-bottom" data-lang="json" data-lang-label="JSON">
    <pre class="line-numbers"><code class="prism language-json" data-prism>{
    "data": {
        "accountGet": {
            "_id": "...",
            "email": "..."
        },
        "localeGet": {
            "ip": "..."
        }
    }
}</code></pre></div>

<p>If there was no authenticated user, the <code>accountGet</code> field would fail to resolve. In such a case the value of the data key for that field will be null, and an object will be added to the errors array instead.</p>

<div class="ide margin-bottom" data-lang="json" data-lang-label="JSON">
    <pre class="line-numbers"><code class="prism language-json" data-prism>{
    "data": {
        "accountGet": null,
        "localeGet": {
            "ip": "...",
            "country": "..."
        }
    },
    "errors": [
        {
            "message": "User (role: guest) missing scope (account)",
            "path": ["accountGet"]
        }
    ]
}</code></pre></div>

<p>Batching with a single query or mutation has some down-sides. You can not mix and match queries and mutations within the same request unless you provide an operationName, in which case you can only execute one query per request.</p>

<p>Additionally, all <b>variables</b> must be passed in the same object, which can be cumbersome and hard to maintain.</p>

<p>The second way to batch is to pass an array of queries or mutations in the request. In this way, you can execute queries <b>and</b> mutations and keep variables separated for each.</p>

<div class="ide margin-bottom" data-lang="json" data-lang-label="JSON">
    <pre class="line-numbers"><code class="prism language-json" data-prism>[
    {
        "query": "query GetAccount { accountGet{ email } }",
    },
    {
        "query": "query GetLocale { localeGet { ip } }"
    }
]</code></pre></div>

<p>This allows you to execute complex actions in a single network request.</p>

<h3><a href="/docs/graphql#sdk-usage" id="sdk-usage">SDK Usage</a></h3>

<p>Appwrite SDKs also support GraphQL in addition to the REST services.</p>

<ul class="phases clear" data-ui-phases>
    <li>
        <h3>Web</h3>
        <div class="ide margin-bottom" data-lang="javascript" data-lang-label="Web SDK">
            <pre class="line-numbers"><code class="prism language-javascript" data-prism>import { Client, Graphql } from "appwrite";

const client = new Client()
    .setEndpoint('https://cloud.appwrite.io/v1') // Your Appwrite Endpoint
    .setProject('[PROJECT_ID]');                // Your project ID

const graphql = new Graphql(client);

const mutation = graphql.mutation({
    query: `mutation CreateAccount(
        $email: String!,
        $password: String!,
        $name: String
    ) {
        accountCreate(
            email: $email,
            password: $password,
            name: $name,
            userId: "unique()"
        ) {
            _id
        }
    }`,
    variables: {
        email: '...',
        password: '...',
        name: '...'
    }
});

mutation.then(response => {
    console.log(response);
}).catch(error => {
    console.log(error);
});</code></pre>
        </div>
    </li>
    <li>
        <h3>Flutter</h3>

        <div class="ide margin-bottom" data-lang="dart" data-lang-label="Flutter SDK">
            <pre class="line-numbers"><code class="prism language-dart" data-prism>import 'package:appwrite/appwrite.dart';

final client = Client()
    .setEndpoint('https://cloud.appwrite.io/v1') // Your Appwrite Endpoint
    .setProject('[PROJECT_ID]');               // Your project ID

final graphql = Graphql(client);

Future mutation = graphql.mutation({
    'query': '''mutation CreateAccount(
        \$email: String!,
        \$password: String!,
        \$name: String
    ) {
        accountCreate(
            email: \$email,
            password: \$password,
            name: \$name,
            userId: "unique()"
        ) {
            _id
        }
    }''',
    'variables': {
        'email': '...',
        'password': '...',
        'name': '...'
    }
});

mutation.then((response) {
    print(response);
}).catchError((error) {
    print(error.message);
});</code></pre>
        </div>
    </li>
    <li>
        <h3>Android</h3>
        <div class="ide margin-bottom" data-lang="android" data-lang-label="Android SDK">
            <pre class="line-numbers"><code class="prism language-kotlin" data-prism>import io.appwrite.Client
import io.appwrite.services.Graphql

val client = Client(context)
    .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
    .setProject("[PROJECT_ID]")                // Your project ID

val graphql = Graphql(client)

try {
    val response = graphql.mutation(mapOf(
        "query" to """mutation CreateAccount(
            ${'$'}email: String!,
            ${'$'}password: String!,
            ${'$'}name: String
        ) {
            accountCreate(
                email: ${'$'}email,
                password: ${'$'}password,
                name: ${'$'}name,
                userId: "unique()"
            ) {
                _id
            }
        }""",
        "variables" to mapOf(
            "email" to "...",
            "password" to "...",
            "name" to "..."
        )
    ))

    Log.d(javaClass.name, response)
} catch (ex: AppwriteException) {
    ex.printStackTrace()
}</code></pre>
        </div>
    </li>
    <li>
        <h3>Apple</h3>
        <div class="ide margin-bottom" data-lang="apple" data-lang-label="Apple SDK">
            <pre class="line-numbers"><code class="prism language-swift" data-prism>import Appwrite

let client = Client()
    .setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
    .setProject("[PROJECT_ID]")                // Your project ID

let graphql = Graphql(client)

do {
    let response = try await graphql.mutation([
        "query": """
            mutation CreateAccount(
                $email: String!,
                $password: String!,
                $name: String
            ) {
                accountCreate(
                    email: $email,
                    password: $password,
                    name: $name,
                    userId: "unique()"

                ) {
                    _id
                }
            }
        """,
        "variables": [
            "email": "...",
            "password": "...",
            "name": "..."
        ]
    ])

    print(String(describing: response))
} catch {
    print(error.localizedDescription)
}</code></pre>
        </div>
    </li>
</ul>