This simple server illustrates how to serve GraphQL requests. It uses:
- The Graphene package for Python
- The psycopg2 module to connect to Postgre
- A PostgreSQL database set up with the DVD Rental example database.
- A simple Flask server to process requests from the GraphQL client
- The GraphiQL browser-based GraphQL client
- Clone the repository via Git.
% git clone https://github.com/tu-cos-343/graphql-example.git
- Change directory to your shiny new clone.
% cd graphql-example
- Create a Python3 virtual environment.
% python3 -m venv venv
- Install the required Python packages.
% pip install -r requirements.txt
- Update the database connection parameters
near the top of
schema.py
Find the Flask server in app.py
.
It uses flask-graphql
to interface with the Graphene package
using a specialized view function called GraphQLView
.
Run the server from the command line:
% python app.py
By default,
the Flask configuration will listen on
http://localhost:5000.
Because app.py
enables GraphiQL support,
you can access the GraphiQL IDE in your browser
at
http://localhost:5000/graphql.
The schema.py
file
implements our GraphQL schema.
You will find extensive comments in that file
that explain the various pieces and parts.
Please take the time to read over the comments
so that you understand how it works.
Following are examples of queries and mutations
that the schema.py
file implements.
Note that if you are connecting to a read-only
database account,
you will not be able to execute the mutations.
-
Retrieve all the films in the database. Note that we also ask for the actors, which causes the
resolve_actors
method to run.query AllFilms { films { filmId title description actors { fullName } } }
-
Retrieve a single actor. Here the
actorId
is passed as a parameter.query OneActor($id: Int!) { actor(actorId: $id) { firstName lastName lastUpdate } }
In
GraphiQL
, use the Query Variables window to supply a JSON object with the ID. For example:{ "id": 42 }
-
Add a new category. Passes the name for the category directly. Probably better to use a parameter as shown for
OneActor
.mutation AddCategory { createCategory(name: "Nerd Films") { categoryId name } }
-
Delete a category. Delete an existing category by its category ID. Note that the database will still enforce referential integrity if another database entity refers to the category being deleted.
mutation DeleteCategory($id: Int!) { deleteCategory(categoryId: $id) { rowsAffected } }
-
Create an actor.
mutation NewActor($input: ActorInput!) { createActor(actorInput: $input) { actorId firstName lastName } }
Pass the details in the Query Variables window
{ "input": { "firstName": "Fred", "lastName": "Ziffle" } }