4. GraphQL

In order to set up GraphQL access to the database we need to update the schema:

Copy
using extension graphql;

module default {
    type Person {
        required property first_name -> str;
        property last_name -> str;
        property name :=
            .first_name ++ ' ' ++ .last_name
            IF EXISTS .last_name
            ELSE .first_name;
    }
    type Movie {
        required property title -> str;
        # the year of release
        property year -> int64;
        required link director -> Person;
        multi link actors -> Person;
    }
};

After the schema is updated, we use the migration tools to create a new migration and apply it:

Copy
$ 
edgedb -I tutorial create-migration
did you create extension 'graphql'? [y,n,l,c,b,s,q,?]
y
Created ./dbschema/migrations/00004.edgeql, id:
m12exapirxxcs227zb2sruf7byvupbt6klkyl5ib6nyklyg3xo5s7a
Copy
$ 
edgedb -I tutorial migrate
Applied m12exapirxxcs227zb2sruf7byvupbt6klkyl5ib6nyklyg3xo5s7a
(00004.edgeql)

This will expose GraphQL API via http. Each EdgeDB instance will be exposed on its corresponding port. Look at $HOME/.edgedb/credentials/tutorial.json file to find out the port for the tutorial instance. For the purpose of the example, we’ll pretend that our tutorial instance is using port 5656 and so the GraphQL API is exposed on: http://127.0.0.1:5656/db/edgedb/graphql. Pointing your browser to http://127.0.0.1:5656/db/edgedb/graphql/explore will bring up a GraphiQL interface to EdgeDB. This interface can be used to try out queries and explore the GraphQL capabilities.

Let’s look at a basic Movie query:

Copy
{
    Movie {
        title
        year
    }
}

Which results in:

Copy
{
  "data": {
    "Movie": [
      {
        "title": "Blade Runner 2049",
        "year": 2017
      },
      {
        "title": "Dune",
        "year": null
      }
    ]
  }
}

It’s possible to apply a filter to get a specific Movie:

Copy
{
    Movie(filter: {title: {eq: "Dune"}}) {
        title
        year
        director { name }
        actors { name }
    }
}

Which results in:

Copy
{
  "data": {
    "Movie": [
      {
        "title": "Dune",
        "year": null,
        "director": {
          "name": "Denis Villeneuve"
        },
        "actors": [
          {
            "name": "Jason Momoa"
          },
          {
            "name": "Zendaya"
          },
          {
            "name": "Oscar Isaac"
          }
        ]
      }
    ]
  }
}

If we wanted to provide some customized information, like which Movie a Person acted in without altering the existing types, we could do that by creating an alias instead. Let’s add that alias to the schema:

Copy
using extension graphql;

module default {
    type Person {
        required property first_name -> str;
        property last_name -> str;
        property name :=
            .first_name ++ ' ' ++ .last_name
            IF EXISTS .last_name
            ELSE .first_name;
    }
    type Movie {
        required property title -> str;
        # the year of release
        property year -> int64;
        required link director -> Person;
        multi link actors -> Person;
    }
    alias PersonAlias := Person {
        acted_in := Person.<actors[IS Movie]
    };
};

Then we create a new migration and apply it:

Copy
$ 
edgedb -I tutorial create-migration
did you create alias 'default::PersonAlias'? [y,n,l,c,b,s,q,?]
y
Created ./dbschema/migrations/00005.edgeql, id:
m1td3ogdzqhztdaivw5bem4sjl3otxfx6fmqngzayymqfwtwbolroa
Copy
$ 
edgedb -I tutorial migrate
Applied m1td3ogdzqhztdaivw5bem4sjl3otxfx6fmqngzayymqfwtwbolroa
(00005.edgeql)

Now, after reloading the GraphiQL page, we will be able to access the PersonAlias:

Copy
{
    PersonAlias(order: {first_name: {dir: ASC}}) {
        name
        acted_in { title }
    }
}

Which results in:

Copy
{
  "data": {
    "PersonAlias": [
      {
        "name": "Ana de Armas",
        "acted_in": [
          {
            "title": "Blade Runner 2049"
          }
        ]
      },
      {
        "name": "Denis Villeneuve",
        "acted_in": []
      },
      {
        "name": "Harrison Ford",
        "acted_in": [
          {
            "title": "Blade Runner 2049"
          }
        ]
      },
      {
        "name": "Jason Momoa",
        "acted_in": [
          {
            "title": "Dune"
          }
        ]
      },
      {
        "name": "Oscar Isaac",
        "acted_in": [
          {
            "title": "Dune"
          }
        ]
      },
      {
        "name": "Ryan Gosling",
        "acted_in": [
          {
            "title": "Blade Runner 2049"
          }
        ]
      },
      {
        "name": "Zendaya",
        "acted_in": [
          {
            "title": "Dune"
          }
        ]
      }
    ]
  }
}
Light
Dark
System