Table of Contents
- Introduction
- Prerequisites
- Setup
- Creating a GraphQL Schema
- Defining GraphQL Types
- Resolvers and Queries
- Mutations
- Testing the GraphQL API
- Conclusion
Introduction
In this tutorial, we will learn how to build a GraphQL API using Python. GraphQL is a query language for APIs and a runtime that allows clients to request and fetch the specific data they need, making it efficient and flexible. By the end of this tutorial, you will have a good understanding of how to create a GraphQL API in Python.
Prerequisites
To follow along with this tutorial, you should have a basic understanding of Python. Familiarity with web development concepts and knowledge of REST APIs will also be helpful.
Setup
Before we start building our GraphQL API, let’s set up our development environment.
- Make sure you have Python installed on your machine. You can check the installation by running the following command in your terminal:
python --version
If Python is not installed, download and install it from the official Python website.
- Install the necessary Python packages. We will be using
graphene
, a Python library for building GraphQL APIs, andflask
, a lightweight web framework. Run the following command to install these packages:pip install graphene flask
- Create a new directory for your project and navigate into it:
mkdir graphql-api && cd graphql-api
- Now, let’s create a new Python file called
app.py
:touch app.py
Open the file in your preferred text editor and let’s start building our GraphQL API!
Creating a GraphQL Schema
Every GraphQL API starts with a schema. A schema defines the types of data that can be queried and the relationships between them. Let’s create a simple schema for a blog API.
- Import the necessary packages in
app.py
:from flask import Flask from graphene import ObjectType, String, Schema
- Create a Flask app instance:
app = Flask(__name__)
- Define a simple
Post
object type with fields such astitle
andcontent
:class Post(ObjectType): title = String() content = String()
- Create a root query class that will define the available queries in our API. In this case, we’ll have a single query
post
, which will return a dummy blog post:class Query(ObjectType): post = String() def resolve_post(root, info): return { 'title': 'My First Blog Post', 'content': 'This is my first blog post using GraphQL!', }
- Create a schema instance and bind it to the Flask app in the main section of
app.py
:schema = Schema(query=Query) if __name__ == '__main__': app.run()
Congratulations! You have created a basic GraphQL schema for your blog API.
Defining GraphQL Types
Now that we have a schema, let’s dive deeper into defining GraphQL types. GraphQL comes with built-in scalar types such as String
, Int
, Float
, Boolean
, and ID
. We can also create custom types to represent more complex data structures.
- Import the
DateTime
scalar type fromgraphene
:from graphene import DateTime
- Add a
published_at
field of typeDateTime
to thePost
object type:class Post(ObjectType): title = String() content = String() published_at = DateTime()
- Update the
resolve_post()
method in theQuery
class to include thepublished_at
field:def resolve_post(root, info): return { 'title': 'My First Blog Post', 'content': 'This is my first blog post using GraphQL!', 'published_at': datetime.now().isoformat(), }
Here, we are using the
datetime
module to generate the current date and time in ISO format. - Restart the Flask development server by running the
app.py
script again. You can use the following command:python app.py
Now, when you navigate to
http://localhost:5000/graphql
, you should see a GraphQL playground where you can interact with the API.
Resolvers and Queries
In GraphQL, resolvers are functions responsible for fetching the data requested by the client. Let’s create another resolver to fetch multiple blog posts.
- Add a
posts
field of type list ofPost
to theQuery
class:class Query(ObjectType): post = String() posts = List(Post) def resolve_post(root, info): return { 'title': 'My First Blog Post', 'content': 'This is my first blog post using GraphQL!', 'published_at': datetime.now().isoformat(), } def resolve_posts(root, info): return [ { 'title': 'Second Blog Post', 'content': 'This is my second blog post using GraphQL!', 'published_at': datetime.now().isoformat(), }, { 'title': 'Third Blog Post', 'content': 'This is my third blog post using GraphQL!', 'published_at': datetime.now().isoformat(), }, ]
-
Restart the Flask development server and navigate to
http://localhost:5000/graphql
. You can now query theposts
field to fetch multiple blog posts.Example query:
query { posts { title content published_at } }
This will return a list of blog posts with their respective titles, content, and published dates.
Mutations
In addition to queries, GraphQL also supports mutations for modifying data. Let’s add a mutation to create a new blog post.
- Define a mutation class with a
create_post
mutation:class CreatePost(Mutation): class Arguments: title = String(required=True) content = String(required=True) success = Boolean() post = Field(Post) def mutate(root, info, title, content): new_post = { 'title': title, 'content': content, 'published_at': datetime.now().isoformat(), } return CreatePost(success=True, post=new_post)
In this example, the mutation takes two arguments,
title
andcontent
, both of which are required. The mutation returns a boolean fieldsuccess
and the newly createdpost
. - Add the
CreatePost
mutation to theMutation
class:class Mutation(ObjectType): create_post = CreatePost.Field()
Now, we have added the mutation to our schema.
-
Restart the Flask development server and navigate to
http://localhost:5000/graphql
. You can now test thecreatePost
mutation to create a new blog post.Example mutation:
mutation { createPost(title: "New Post", content: "This is a new blog post") { success post { title content published_at } } }
This will create a new post with the provided title and content and return the success status along with the created post.
Testing the GraphQL API
To test the API using Python, we can use the requests
library to make HTTP requests and interact with the GraphQL API.
- Install the
requests
package by running the following command:pip install requests
- Import the necessary package in
app.py
:import requests
- Create a
test_query()
function to send a GraphQL query to the API:def test_query(query): url = 'http://localhost:5000/graphql' response = requests.post(url, json={'query': query}) return response.json()
- Call the
test_query()
function with a sample query as an argument to test the API:query = ''' query { posts { title content published_at } } ''' print(test_query(query))
This will print the response of the query to the console.
Conclusion
Congratulations! You have successfully built a GraphQL API in Python using the graphene
and flask
libraries. You learned how to create a GraphQL schema, define object types, write resolvers for queries and mutations, and test the API using a GraphQL playground and Python’s requests
library. With this knowledge, you can start building powerful and flexible APIs with GraphQL in Python.
Throughout this tutorial, you covered the basics of building a GraphQL API. However, there is much more to explore, such as input types, interfaces, subscriptions, and integrating with databases or other services. Feel free to dive deeper into the official documentation and explore more advanced concepts to enhance your GraphQL API.
Note: It’s important to note that this tutorial serves as a starting point for building GraphQL APIs in Python. The implementation and structure may vary depending on the specific requirements and frameworks you are using.