On this page

Medplum supports the [FHIR GraphQL API](https://hl7.org/fhir/r4/graphql.html) for creating, updating and searching FHIR resources.

Clinical data is often comprised of multiple FHIR resources, and the FHIR GraphQL API makes it easy to query multiple linked resources in a single request.

The GraphQL API also allows you to request specific elements, rather than full resources, which can be more efficient in bandwidth constrained settings.

To experiment with the API, you can use Medplum's interactive GraphQL environment at [graphiql.medplum.com](https://graphiql.medplum.com/). You can log in with your Medplum credentials, and run these example queries in the GraphiQL IDE.

## Schema Introspection
Schema introspection is supported on Medplum, but for security and performance reasons, it is disabled by default. To enable it, you will need to enable the `introspectionEnabled` flag in your server config.

## How to perform basic GraphQL queries [​](/content/docs/graphql#how-to-perform-basic-graphql-queries "Direct link to How to perform basic GraphQL queries"/index.html)
GraphQL queries allow you to request specific resourced fields. In a FHIR GraphQL query, you will use the resource type as the root, followed by the ID in parentheses. The requested fields are enclosed in curly braces.

For example, to request a `Patient` by ID:

- GraphQL
- TypeScript
- cURL

```graphql
{
  Patient(id: "example-id") {
    resourceType
    id
    name {
      text
    }
    address {
      text
    }
  }
}
```
```ts
const patientId = 'example-id';
await medplum.graphql(`
{
  Patient(id: "${patientId}") {
    resourceType
    id
    name {
      text
    }
    address {
      text
    }
  }
}`);
```
```bash
curl -X POST 'https://api.medplum.com/fhir/R4/$graphql' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $your_access_token" \
  -d '{"query": "{ Patient(id: \"example-id\") { resourceType id name { text } address { text } } }"}'
```

Example Response
```ts
{
  data: {
    Patient: {
      resourceType: 'Patient',
      id: 'example-id',
      name: [
        {
          text: 'John Doe',
        },
      ],
      address: [
        {
          text: '123 Main St, Springfield',
        },
      ],
    },
  },
};
```
This query retrieves the `resourceType`, `id`, `name`, and `address` of the specified `Patient`.

## Access Policies
When using GraphQL, [access policies](/content/docs/access/access-policies/index.html) are enforced, so users will not be able to read or edit any resources (or inner fields) they do not have access to.

## How to perform FHIR searches with GraphQL [​](/content/docs/graphql#how-to-perform-fhir-searches-with-graphql "Direct link to How to perform FHIR searches with GraphQL"/index.html)
To perform a FHIR search, append the word "List" to the FHIR resource type. For example, to search for Patient resources use "PatientList". You will specify search parameters as query parameters, similarly to [basic REST search](/content/docs/search/basic-search/index.html).

GraphQL also allows you to [alias returned fields](https://devinschulz.com/rename-fields-by-using-aliases-in-graphql/) to make the results more readable.

Warning
When using FHIR GraphQL, you must still use [FHIR search parameters](/content/docs/search/basic-search#search-parameters/index.html); however, the search parameter names use **snake_case** instead of the **kebab-case** commonly used in the FHIR REST API.

To search for a list of `Patient` resources with a specific name and city:

- GraphQL
- TypeScript
- cURL

```graphql
{
  PatientList(name: "Eve", address_city: "Philadelphia") {
    resourceType
    id
    name {
      family
      given
    }
    address {
      line
      city
      state
      postalCode
    }
  }
}
```
```ts
await medplum.graphql(`
{
  patients: PatientList(name: "Eve", address_city: "Philadelphia") {
    resourceType
    id
    name {
      family
      given
    }
    address {
      line
      city
      state
      postalCode
    }
  }
}`);
```
```bash
curl 'https://api.medplum.com/fhir/R4/$graphql' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $your_access_token" \
  -d '{"query":"{ PatientList(name: \"Eve\", address_city: \"Philadelphia\") { resourceType id name { family given } address { line city state postalCode } } }"}'
```

Example Response
```ts
data: {
  patients: [
    {
      resourceType: 'Patient',
      id: 'example-id-1',
      name: [
        {
          family: 'Johnson',
          given: ['Eve'],
        },
      ],
      address: [
        {
          line: ['456 Market St'],
          city: 'Philadelphia',
          state: 'PA',
          postalCode: '19104',
        },
      ],
    },
    {
      resourceType: 'Patient',
      id: 'example-id-2',
      name: [
        {
          family: 'Smith',
          given: ['Eve'],
        },
      ],
      address: [
        {
          line: ['789 Broad St'],
          city: 'Philadelphia',
          state: 'PA',
          postalCode: '19107',
        },
      ],
    },
  ],
},
```
This query searches for Patient resources with the name "Eve" and a city of "Philadelphia", and aliases the list of patients as `patients` in the response.

## Resolving nested resources with the `resource` element [​](/content/docs/graphql#resolving-nested-resources-with-the-resource-element "Direct link to resolving-nested-resources-with-the-resource-element"/index.html)
Clinical data is often spread across multiple FHIR resources that reference each other. The FHIR GraphQL API contains a special `resource` element to resolve these references and retrieve the nested resources.

To resolve a reference, you need to use the GraphQL inline fragment syntax `(... on ResourceType)`. Inline fragments allow you to request fields on a specific type within a more general parent type. This is important for FHIR GraphQL queries because the resource field can return different types of resources depending on the reference.

For example, to retrieve a `DiagnosticReport` and all the `Observation` resources referenced by `DiagnosticReport.result`:

- GraphQL
- TypeScript
- cURL

```graphql
{
  DiagnosticReport(id: "example-id-1") {
    resourceType
    id
    result {
      resource {
        ... on Observation {
          resourceType
          id
          valueQuantity {
            value
            unit
          }
        }
      }
    }
  }
}
```
```ts
await medplum.graphql(`
{
  DiagnosticReport(id: "example-id-1") {
    resourceType
    id
    result {
      resource {
        ... on Observation {
          resourceType
          id
          valueQuantity {
            value
            unit
          }
        }
      }
    }
  }
}`);
```
```bash
curl 'https://api.medplum.com/fhir/R4/$graphql' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $your_access_token" \
  -d '{"query":"{ DiagnosticReport(id: \"example-id-1\") { resourceType id result { resource { ... on Observation { resourceType id valueQuantity { value unit } } } } } }"}'
```

Example Response
```ts
data: {
  DiagnosticReport: {
    resourceType: 'DiagnosticReport',
    id: 'example-id-1',
    result: [
      {
        resource: {
          resourceType: 'Observation',
          id: 'observation-id-1',
          valueQuantity: {
            value: 5.5,
            unit: 'mg/dL',
          },
        },
      },
      {
        resource: {
          resourceType: 'Observation',
          id: 'observation-id-2',
          valueQuantity: {
            value: 3.2,
            unit: 'mg/dL',
          },
        },
      },
    ],
  },
},
```
This query retrieves a `DiagnosticReport` and the `Observation` resources associated with it.

## Searching reverse references using the `_reference` keyword [​](/content/docs/graphql#searching-reverse-references-using-the-_reference-keyword "Direct link to searching-reverse-references-using-the-_reference-keyword"/index.html)
FHIR GraphQL also supports reverse-reference searches, which allow you to find resources that _point to_ the current resource.

In a reverse-include search, you use a nested `<ResourceType>List` block to search for the resources that reference the current resource. The special `_reference` search parameter indicates which search parameter from the target resource references the current resource.

In the example below, we first search for a `Patient` by id, and then find all the `Encounter` resources whose `Encounter.patient` search parameter points to the current Patient.
- GraphQL
- TypeScript
- cURL

```graphql
{
  Patient(id: "example-patient-id") {
    resourceType
    id
    encounters: EncounterList(_reference: patient) {
      resourceType
      id
    }
  }
}
```
```ts
await medplum.graphql(`
{
  Patient(id: "example-patient-id") {
    resourceType
    id
    encounters: EncounterList(_reference: patient) {
      resourceType
      id
    }
  }
}`);
```
```bash
curl -X POST 'https://api.medplum.com/fhir/R4/$graphql' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $your_access_token" \
  -d '{"query":"{ Patient(id: \"example-patient-id\") { resourceType id encounters: EncounterList(_reference: patient) { resourceType id } } }"}'
```

Example Response
```ts
data: {
  Patient: {
    resourceType: 'Patient',
    id: 'example-patient-id',
    encounters: [
      {
        resourceType: 'Encounter',
        id: 'encounter-id-1',
      },
      {
        resourceType: 'Encounter',
        id: 'encounter-id-2',
      },
    ],
  },
},
```
See the " [Reverse References](https://www.hl7.org/fhir/graphql.html#searching)" section of the FHIR GraphQL specification for more information.

## Chained Search in GraphQL
When searching on references in GraphQL, you _cannot_ filter on the parameters of the referenced resources. This is called chained search and it is not supported by the FHIR GraphQL spec. However, it is supported in the FHIR Rest API. For more details see the [Chained Search docs](/content/docs/search/chained-search/index.html).

## Filtering lists with field arguments [​](/content/docs/graphql#filtering-lists-with-field-arguments "Direct link to Filtering lists with field arguments"/index.html)
FHIR GraphQL supports filtering array properties using field arguments. For example, you can filter the `Patient.name` array by the `use` field:
- GraphQL
- TypeScript
- cURL

```graphql
{
  PatientList {
    resourceType
    id
    name(use: "official") {
      given
      family
    }
  }
}
```
```ts
await medplum.graphql(`
{
  PatientList {
    resourceType
    id
    name(use: "official") {
      given
      family
    }
  }
}
`);
```
```bash
curl -X POST 'https://api.medplum.com/fhir/R4/$graphql' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $your_access_token" \
  -d '{"query":"{ PatientList { resourceType id name(use: \"official\") { use given family } extension(url: \"https://example.com/extension-url-2\") { value : valueString } } }"}'
```

Example Response
```ts
data: {
  PatientList: [
    {
      resourceType: 'Patient',
      id: 'patient-id-1',
      name: [
        {
          given: ['John'],
          family: 'Doe',
        },
      ],
    },
  ],
},
```
Another common use is to filter an `extension` array by `url`:
- GraphQL
- TypeScript
- cURL

```graphql
{
  PatientList {
    resourceType
    id
    extension(url: "https://example.com/123") {
      valueString
    }
  }
}
```
```ts
await medplum.graphql(`
{
  PatientList {
    resourceType
    id
    extension(url: "https://example.com/123") {
      valueString
    }
  }
}`);
```
```bash
curl -X POST 'https://api.medplum.com/fhir/R4/$graphql' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $your_access_token" \
  -d '{"query":"{ PatientList { resourceType id extension(url: \"https://example.com/123\") { valueString } } }"}'
```

Example Response
```ts
data: {
  PatientList: [
    {
      resourceType: 'Patient',
      id: 'patient-id-1',
      extension: [
        {
          valueString: 'Sample extension value',
        },
      ],
    },
  ],
},
```
If more powerful filtering capabilities are required, a FHIRPath expression can be evaluated to select which list items are included in the response. The expression should evaluate to `true` for an item to be included. This example selects all patient names without a family part:
- GraphQL
- TypeScript

```graphql
{
  PatientList {
    resourceType
    id
    name(fhirpath: "family.exists().not()") {
      use given family text
    }
  }
}
```
```ts
await medplum.graphql(`{
  PatientList {
    resourceType
    id
    name(fhirpath: "family.exists().not()") {
      use given family text
    }
  }
}`);
```

Example Response
```ts
data: {
  PatientList: [
    {
      resourceType: 'Patient',
      id: 'patient-id-1',
      name: [
        {
          use: 'usual',
          given: ['Johnny'],
          family: null,
          text: null,
        },
        {
          use: 'anonymous',
          given: null,
          family: null,
          text: 'd87a7e2f264680fe',
        },
      ],
    },
  ],
},
```

## Query Performance
Evaluating FHIRPath expressions can be relatively expensive; consider whether results could easily be filtered by the client instead.
See the " [List Navigation](https://hl7.org/fhir/r4/graphql.html#list)" section of the FHIR GraphQL specification for more information.

## Putting it all together [​](/content/docs/graphql#putting-it-all-together "Direct link to Putting it all together"/index.html)
The FHIR GraphQL syntax is a powerful way to query for multiple related resources in a single HTTP call. The following example combines previous concepts.
This query searches for a list of `Patients` named "Eve", living in "Philadelphia", and then searches for all `DiagnosticReports` linked to each `Patient` along with their corresponding `Observations`.
- GraphQL
- TypeScript
- cURL

```graphql
{
  PatientList(name: "Eve", address_city: "Philadelphia") {
    resourceType
    id
    name {
      family
      given
    }
    address {
      line
      city
      state
      postalCode
    }
    reports: DiagnosticReportList(_reference: subject) {
      resourceType
      id
      result {
        resource {
          ... on Observation {
            resourceType
            id
            valueQuantity {
              value
              unit
            }
          }
        }
      }
    }
  }
}
```
```ts
await medplum.graphql(`
{
  PatientList(name: "Eve", address_city: "Philadelphia") {
    resourceType
    id
    name {
      family
      given
    }
    address {
      line
      city
      state
      postalCode
    }
    reports: DiagnosticReportList(_reference: subject) {
      resourceType
      id
      result {
        resource {
          ... on Observation {
            resourceType
            id
            valueQuantity {
              value
              unit
            }
          }
        }
      }
    }
  }
}
`);
```
```bash
curl -X POST 'https://api.medplum.com/fhir/R4/$graphql' \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $your_access_token" \
  --data-raw '{"query":"query { PatientList(name: \"Eve\", address_city: \"Philadelphia\") { resourceType id name { family given } address { line city state postalCode } DiagnosticReportList(_reference: subject) { resourceType id result { resource { ... on Observation { resourceType id valueQuantity { value unit } } } } } } }"}'
```

Example Response
```ts
data: {
  PatientList: [
    {
      resourceType: 'Patient',
      id: 'patient-id-1',
      name: [
        {
          family: 'Smith',
          given: ['Eve'],
        },
      ],
      address: [
        {
          line: ['123 Main St'],
          city: 'Philadelphia',
          state: 'PA',
          postalCode: '19107',
        },
      ],
      reports: [
        {
          resourceType: 'DiagnosticReport',
          id: 'report-id-1',
          result: [
            {
              resource: {
                resourceType: 'Observation',
                id: 'observation-id-1',
                valueQuantity: {
                  value: 5.5,
                  unit: 'mg/dL',
                },
              },
            },
          ],
        },
      ],
    },
    {
      resourceType: 'Patient',
      id: 'patient-id-2',
      name: [
        {
          family: 'Johnson',
          given: ['Eve'],
        },
      ],
      address: [
        {
          line: ['456 Oak St'],
          city: 'Philadelphia',
          state: 'PA',
          postalCode: '19107',
        },
      ],
      reports: [
        {
          resourceType: 'DiagnosticReport',
          id: 'report-id-2',
          result: [
            {
              resource: {
                resourceType: 'Observation',
                id: 'observation-id-2',
                valueQuantity: {
                  value: 6.7,
                  unit: 'mg/dL',
                },
              },
            },
          ],
        },
      ],
    },
  ],
},
```
This query retrieves a `PatientList` with respective `reports` for each `Patient`.

## Summary [​](/content/docs/graphql#summary "Direct link to Summary"/index.html)
With a deeper understanding of the FHIR GraphQL syntax, you can now leverage build efficient and flexible FHIR queries for your applications. Remember to experiment with the API at [graphiql.medplum.com](https://graphiql.medplum.com/) as you develop your application.

- [How to perform basic GraphQL queries](/content/docs/graphql#how-to-perform-basic-graphql-queries/index.html)
- [How to perform FHIR searches with GraphQL](/content/docs/graphql#how-to-perform-fhir-searches-with-graphql/index.html)
- [Resolving nested resources with the `resource` element](/content/docs/graphql#resolving-nested-resources-with-the-resource-element/index.html)
- [Searching reverse references using the `_reference` keyword](/content/docs/graphql#searching-reverse-references-using-the-_reference-keyword/index.html)
- [Filtering lists with field arguments](/content/docs/graphql#filtering-lists-with-field-arguments/index.html)
- [Putting it all together](/content/docs/graphql#putting-it-all-together/index.html)
- [Summary](/content/docs/graphql#summary/index.html)
