GraphQL endpoints
Overview
The Fauna GraphQL API provides three endpoints:
-
/graphql
, for query execution. -
/import
, for schema management. -
/ping
, for testing connectivity to the GraphQL API.
The full endpoint URL depends on the Region Group you selected for your database. Fauna currently supports three Region Groups for decreased latency and improved data locality:
-
United States (US)
-
Europe (EU)
-
Classic (Europe and United States)
The full endpoint URL for each Region Group is listed in the following table:
Region Group | Endpoint | Description |
---|---|---|
United States (US) |
|
Executes GraphQL queries. |
Europe (EU) |
|
Executes GraphQL queries. |
Classic |
|
Executes GraphQL queries. |
Preview |
|
Executes GraphQL queries. |
GraphQL queries are executed by sending HTTP requests to the
https://<environment>/graphql endpoint. This documentation does not describe how to
implement HTTP requests, as you can do so in many different
languages. Common GraphQL HTTP request information is available
here: https://graphql.org/learn/serving-over-http/
|
The Preview environment is where Fauna provides early access new to features. It is accessible by invitation only. Contact product@fauna.com for an invitation. |
https://<environment>/graphql
The https://<environment>/graphql
endpoint access GraphQL queries, and
returns results in JSON format. See
Getting started with
GraphQL, or the GraphQL
tutorials to see how queries work.
https://<environment>/import
The https://<environment>/import
endpoint accepts a GraphQL schema
definition, which is translated into the equivalent Fauna collections
and indexes.
When a GraphQL schema is imported, the GraphQL API creates the following schema objects in your Fauna database:
-
One collection for each declared GraphQL type (using the type name), with the exception of
@embedded
types. -
One index for each declared query (using the query name), with the exception of queries annotated with the
@resolver
directive. You can use an existing collection with@collection
, and an existing index with@index
. -
When a
@relation
directive is used and the relationship is many-to-many (instead of one-to-one, or one-to-many), an associative collection is created plus three indexes, one for each side of the relationship, and a third covering the full relationship. For more information about many-to-many relationships and associative collections, see GraphQL Relationships. -
One user-defined function for each mutation declared with the
@resolver
directive (using the resolver name). Note that you have to implement the mutation function using FQL yourself. See User-defined functions for details.
The https://<environment>/import endpoint is not for
importing data, it is only for importing a GraphQL schema.
Use GraphQL
mutations to
create or update data.
|
When a GraphQL schema is imported, the GraphQL API enforces that schema for all subsequent GraphQL queries and mutations, until the schema is modified or replaced. Schema enforcement happens in the GraphQL API only: the schema is not enforced at the database level. FQL queries or UDFs can create or mutate documents, in the collections created for the schema, that do not comply with the schema. Such documents could cause queries and mutations to fail. Care must be taken to ensure schema compatibility when using FQL or UDFs to create/mutate documents in GraphQL collections. |
A basic GraphQL schema looks like:
type User {
username: String!
}
type Query {
allUsers: [User!]!
}
After importing a GraphQL schema, you can use the Fauna Dashboard to see all the newly created collections, indexes, and user-defined functions.
This query defines a User
type, which would become a collection in
Fauna called User
:
Get(Collection("User"))
{
ref: Collection("User"),
ts: 1618959271660000,
history_days: 30,
name: "User",
data: {
gql: {
ts: Time("2021-04-20T22:54:31.557442Z"),
meta: {
name: "User",
fields: [
{
name: "username",
type: {
NotNull: {
Named: "String"
}
}
}
],
directives: [
{
name: "collection",
args: {
name: "User"
}
}
]
}
}
}
}
It also defines an allUsers
query that provides paginated User
results. Fauna implements such a query as an index called allUsers
:
Get(Index("allUsers"))
{
ref: Index("allUsers"),
ts: 1618959271800000,
active: true,
serialized: true,
name: "allUsers",
source: Collection("User"),
data: {
gql: {
ts: Time("2021-04-20T22:54:31.700473Z"),
meta: {
name: "allUsers",
directives: [
{
name: "index",
args: {
name: "allUsers"
}
}
],
type: {
NotNull: {
List: {
NotNull: {
Named: "User"
}
}
}
}
}
}
},
unique: false,
partitions: 8
}
For end-to-end examples of importing a schema, creating records, and querying them, see Getting started with GraphQL.
Modes
There are three import modes:
Mode | Description | ||
---|---|---|---|
|
The Since index definitions cannot be edited after creation,
|
||
|
The Since index definitions cannot be edited after creation,
|
||
|
The The purpose of
|
Specify the mode using a query parameter. For example:
POST /import?mode=replace
If you are using curl
, the command would look like:
curl -H 'Authorization: Bearer <FAUNA_SECRET>' https://<environment>/import?mode=replace --data-binary "@path/to/schema.gql"
Where FAUNA_SECRET
is a secret
associated with the database where the schema should be imported, and
path/to/schema.gql
is the path to a file with your GraphQL schema.
Handling import errors
When errors are encountered during schema import, they most often involve index definitions. Once an index exists, its definition cannot be modified. There are two strategies that you can use to resolve the errors:
-
Create replacement indexes that define the appropriate
terms
andvalues
definitions. There are two ways to use the replacement indexes:-
Renaming the existing index, and then create a new index using the correct definition and the original index name.
-
Create the new index with a new name and correct definition, then update your schema using the
@index
directive directive.
Once you know that the new index works correctly for your queries and mutations, and that the original index is no longer needed, you can delete the original index.
-
-
Use
override
mode. This deletes all collections, indexes, and functions defined by the current schema, then the new schema is imported creating the required collections, indexes, and functions. The drawback is that all documents are deleted.Note that it is possible for
override
mode to end with an error. GraphQL schemas often require indexes with precise definitions to model relationships between types. When a new schema requires an index, and an index exists with the desired name but an incompatible definition, the GraphQL API abortsoverride
mode to avoid interfering with FQL queries. You should assess whether adjusting your schema, or renaming existing indexes and updating FQL queries, is the better approach.
Authentication
Endpoints require authentication for a Fauna database. This is achieved with a standard Fauna secret, which determines the database and permissions to be used.
The secret can be provided through the HTTP Authentication
request
header as a Bearer
token or using HTTP Basic
authentication.
Bearer token
To use the Fauna secret as a Bearer
token, the Authorization
header should look like:
Authorization: Bearer <secret>
For example, if your Fauna secret is
fnADMxRzydATDKibGAciQlNQWBs-HJdpJS1vJaIM
, then your Authorization
header would look like:
Authorization: Bearer fnADMxRzydATDKibGAciQlNQWBs-HJdpJS1vJaIM
If you are using curl
, you can specify the Authorization
header
like so:
curl -H 'Authorization: Bearer fnADMxRzydATDKibGAciQlNQWBs-HJdpJS1vJaIM' ...
HTTP Basic
To use the Fauna secret with HTTP Basic
authentication, include the
secret as the username value. You do not need to include a password.
Make sure that you encode the credentials into a Base64 string. For
example, if your Fauna secret is
fnADMxRzydATDKibGAciQlNQWBs-HJdpJS1vJaIM
, you can convert it to HTTP
Basic credentials like so:
echo -n "fnADMxRzydATDKibGAciQlNQWBs-HJdpJS1vJaIM:" | base64
Zm5BRE14Unp5ZEFUREtpYkdBY2lRbE5RV0JzLUhKZHBKUzF2SmFJTTo=
The trailing colon (: ) is required as it separates
the username and password values.
|
Then your Authorization
header would look like:
Authorization: Basic Zm5BRE14Unp5ZEFUREtpYkdBY2lRbE5RV0JzLUhKZHBKUzF2SmFJTTo=
|
Errors
Authentication errors result in HTTP 401 error responses, with one of the following messages:
Error message | Description |
---|---|
|
The Authorization header is not included in the request. |
|
The value for the Authorization header has an invalid format. |
|
The database secret decoded from the Authorization header is not valid. |
For the /graphql
endpoint, the error message is formatted as JSON:
Status: 200
Content-type: application/json
{
"errors": [
{ "message": "Invalid database secret." }
]
}
For the /import
endpoint, the error message is formatted as plain
text:
Status: 401
Content-type: text/plain
Invalid database secret.
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!