# Designing GraphQL schemas - Dgraph Blog

**URL:** <https://discuss.dgraph.io/t/designing-graphql-schemas-dgraph-blog/6301>\
**Category:** Blog\
**Created:** [April 13, 2020, 5:07pm UTC](https://discuss.dgraph.io/t/designing-graphql-schemas-dgraph-blog/6301 "2020-04-13T17:07:38Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![mrjn](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/mrjn/32/775_2.png) [@mrjn](https://discuss.dgraph.io/u/mrjn)\
**Post date:** [April 13, 2020, 5:08pm UTC](https://discuss.dgraph.io/t/designing-graphql-schemas-dgraph-blog/6301/1 "2020-04-13T17:08:01Z")

</div>

GraphQL has taken the app development world by storm because of its immense benefits. GraphQL adoption by UI development teams has brought in a new wave of flexibility in API design, productivity across frontend-backend teams, intuitiveness in expressing UI data requirements, and accessibility to powerful tooling. These benefits are why many tech companies, including [Facebook](https://engineering.fb.com/core-data/graphql-a-data-query-language/), [Airbnb](https://medium.com/airbnb-engineering/how-airbnb-is-moving-10x-faster-at-scale-with-graphql-and-apollo-aa4ec92d69e2), [Paypal](https://medium.com/paypal-engineering/graphql-a-success-story-for-paypal-checkout-3482f724fb53), [GitHub](https://githubengineering.com/the-github-graphql-api/), and [Shopify](https://shopify.dev/concepts/graphql/benefits), are embracing GraphQL.

Designing the GraphQL schema is often the first step in your app development journey using GraphQL. This guide presents an intuitive, straightforward process to design your GraphQL schemas, and modify them as your application UIs become increasingly complex.

## GraphQL Schema

Expressing the data requirements of your application in your GraphQL schema is easy for simple UIs. However, it can become more difficult as your UI becomes more extensive and more complex. A StackOverflow page or an Amazon product page are classic examples of complex application user interfaces.

Most of the benefits offered by GraphQL are due to **GraphQL Schemas**. _Schemas enable automatic code generation, validation and parsing, introspection, and type safety for your APIs_. In many ways, schemas are like strong typing in programming languages, in that they can catch errors while a system is being constructed, as well as helping deal with errors at runtime.

A GraphQL schema is a description of the data clients can request from a GraphQL API. It also defines the queries and mutation functions that the client can use to read and write data from the GraphQL server. In other words, you specify your client or application UI data requirements in your GraphQL schema.

**Application Data**

Consider a simple blogging application with two distinct app screens.

1. The table of contents lists all the blog posts ![](upload://wj7eCeTe6tz4eJmlTfJH9Q0B0Bs.png)
2. The content page displays a single blog post from the table of contents ![](upload://pr1zzb2v0deP2GnqYbENTIqRk0O.png)

The application data requirement describes all the information your application UI expects to be served from the backend.

The data requirements of the table of contents are:

- A list of titles of the blog posts
- The author names of the blog posts

The data requirements of the content page are:

- The title of the blog post
- The content of the blog post

Once you identify the data requirements, you can group different data entities.

The title and content of the blog can be grouped under a `Blog post` entity. Similarly, the `Author name` or any other Author info can be grouped under the Author entity.

The _Blog_ post entity consists of

- A title

- The content of the post

The _Author_ entity consists of

By making the _Author_ a separate entity, you can associate more than one blog post with an author, and also add more information about an author (e.g., the email address, personal website, etc.) without having to change multiple blog posts.

Data entities are generally related to each other. But how to represent the relationship between different data entities? Read on.

## Your GraphQL schema is a graph

If you've wondered why there is a **Graph** in **GraphQL** , here is the quote from [graphql.org](https://graphql.org/), the official GraphQL site:

> “Graphs are powerful tools for modeling many real-world phenomena because they resemble our natural mental models and verbal descriptions of the underlying process. With GraphQL, you model your business domain as a graph by defining a schema; within your schema, you define different types of nodes and how they connect/relate to one another.”

In short, a **GraphQL schema** is a textual representation of your application's **data graph** and the **operations** on it. Your data graph defines the entities and the relationships between them. But to complete a schema, you usually need to add GraphQL **operations**. The GraphQL operations provide the information needed to generate and validate operations on the data graph.

## Application data graph

To describe the relationship between the two entities in the blog post application mentioned above:

- Each _Blog_ post has an Author
- Each _Author_ can have more than one blog post.

Compared to the rows and columns used in traditional relational databases, graphs are a much easier and more intuitive model to represent data and their relationships. Here is the diagram of the graph model for the blog application: ![](upload://8aC94HbF3wo219lIbhG9EyJPNjM.png)

The graph represents the entities in application data as nodes in the graph, and their relationships are represented as edges. The title, content and author name are represented as properties of the node below the entity names.

By convention, you capitalize entity names. Note that this diagram uses CamelCase (e.g., BlogPost, Author) for entity names, and camelCase for data fields and relationship names. This casing practice is not a requirement, and the GraphQL spec doesn't dictate any convention. This casing practice is widely followed because the same convention can be mapped to data structures representing the object types in your programming language.

Also, the asterisk (\*) near the arrowhead of the _hasBlog_ means this is a one-to-many relationship. A single author can be associated with multiple blog posts, one blog post, or even no blog posts.

The last step in designing the schema is to translate the application data graph into a GraphQL schema.

## Writing the GraphQL schema

The [GraphQL spec](https://spec.graphql.org/June2018/) defines a language called the **Schema Definition Language (SDL)** to write GraphQL schemas.

You use the available types defined by SDL to compose your GraphQL schema. We cover four of the types in this article:

- Object type
- Scalar type
- Query type
- Mutation type

You'll learn more about these types (and others) in upcoming articles.

It can be challenging to represent types as GraphQL schema, especially with complex and extensive UIs. However, follow the four steps below to represent your types as a GraphQL schema like a pro.

### Step 1: Represent the nodes as object types

Based on the data graph of the blog post application above, it has two nodes representing two entities: _BlogPost_ and _Author_. Both entities are represented as object types in the GraphQL schema.

```
type BlogPost {
}
type Author {
}

```

### Step 2: Add the scalar types as fields to the object types

The built-in scalar types in GraphQL are `Int`, `Float`, `String`, `Boolean`, and `ID`. You can add scalar types as fields to the (previously defined) object types in the schema. These scalar types represent the **properties** of their corresponding entities.

The data fields for the `BlogPost` entity are `title` and `content`, and both are type String. If a field is mandatory, specify this with an exclamation point (!).

```
type BlogPost {
  title: String!
  content: String!
}

```

Similarly, add a property called `name` of type `String` to the `Author` object.

```
type Author {
  name: String!
}

```

Defining a field as mandatory is a type modifier, which is not specified in the data graph. If a field is mandatory, that means that its value cannot be undefined or `null`. You can determine if a field is mandatory by figuring out if operations on the graph assume whether this field is defined. For example, a blog post needs a title and some content to be displayed correctly. If a BlogPost entity is created without defining both, an error would be thrown in the result.

### Step 3: Represent the relationships

A relationship in a GraphQL schema is represented by adding an object type as a field inside another object. The edges that are connecting the nodes represent the relationships between the entities.

In the graph above, the edge connecting a `BlogPost` node to an `Author` node is named `hasAuthor`. Add a field named `hasAuthor` of type `Author`, inside the `BlogPost` type to represent this relationship. Note that a blog post has to have an author, in addition to a title and content.

```
type BlogPost {
  title: String!
  content: String!
  # It's required that every blog post has an author
  # Hence the exclamation (!) to mark it as required
  hasAuthor: Author!
}

```

Similarly, the edge connecting an Author node to its BlogPosts is named hasBlog. Add a field hasBlog of type BlogPost, inside the Author type to represent this relationship.

```
type Author {
  name: String!
  # An author can have more than one blog post
  # Hence representing this as an array [BlogPost]
  hasBlog: [BlogPost]
}

```

The square brackets around `[BlogPost]` indicates that the `hasBlog` field is stored as an array. Because an author can be associated with 0, 1, or more blog posts, so the one-to-many relationship was indicated by the asterisk (\*) in the data graph.

This schema represents the application data graph for our blog application.

## The Last Step: Define queries and mutations

While object types help you represent the data graph, they don't help you define the operations on it. To include the operations on the data graph, you need Query types and Mutation types. The `Query` types define the read operations, and the `Mutation` types define the write operations on the data graph. They define the type signatures of operations that are used by your application to read or write data.

For example, to fetch all of the blogs with their tables of content, you need to define a field in the Query type that returns an array of blog posts, like this:

```
type Query {
  # Return all blog posts
  # Satisfies the data requirement for the first page
  getAllBlogs(): [BlogPost]
}
type BlogPost {
  title: String!
  content: String!
  # It's required that every blog post has an author
  # Hence the exclamation (!) to mark it as required
  hasAuthor: Author!
}
type Author {
  name: String!
  # An author can have more than one blog post
  # hence representing this as an array [blogpost]
  hasBlog: [BlogPost]
}

```

Next, you need an operation to fetch a specific blog post. To enable this operation, you need to associate a unique ID with every blog post. The ID of a blog post is used to fetch the blog content for the second application screen.

ID is a scalar type in GraphQL that represents a unique identifier and is added as a field to the BlogPost and Author object type to uniquely identify each Author and their BlogPosts.

```
type BlogPost {
  id: ID!
  title: String!
  content: String!
  # It's required that every blog post has an author
  # Hence the exclamation (!) to mark it as required
  hasAuthor: Author!
}
type Author {
  id: ID!
  name: String!
  # An author can have more than one blog post
  # hence representing this as an array [blogpost]
  hasBlog: [BlogPost]
}

```

Now, you can extend the `Query` type in the schema by adding a `getBlogPost` field; this field can fetch a blog post with its unique ID.

```
type Query {
  # Return all blog posts
  # Satisfies the data requirement for the first page
  getAllBlogs(): [BlogPost]
  # Returns a single blog post given it's ID.
  getBlogPost(id: ID!): BlogPost
}

```

Similarly, you can add fields to the `Mutation` type to create new objects. For example, here is a Mutation field to create new blog posts:

```
type Mutation {
  addBlogPost(title: String!, content: String!, authorID: ID!): BlogPost
}

```

Voila! You have successfully created the GraphQL schema for your simple blog application:

```
type Query {
  getAllBlogs(): [BlogPost]
  getBlogPost(id: ID!): BlogPost
}
type Mutation {
  addBlogPost(title: String!, content: String!, authorID: ID!): BlogPost!
}
type BlogPost {
  id: ID!
  title: String!
  content: String!
  hasAuthor: Author!
}
type Author {
  id: ID!
  name: String!
  hasBlog: [BlogPost]
}

```

For most of the common read-write operations, you can define CRUD functions named for your types. In the blog post application case, you could name them as `addAuthor`, `queryAuthor`, `UpdateAuthor`, and `DeleteAuthor`. You can add more `Query` and `Mutation` functions later to your GraphQL schema for handling custom logic that is more complicated than the basic CRUD operations.

GraphQL schema defines the signature of your GraphQL API, but it's not yet functional.

To make it functional, you still need to run a GraphQL web server, write server-side code, and use a database to store and retrieve the data.

Next, let's dive into how to use [Dgraph GraphQL](https://dgraph.io/graphql) to obtain production-grade, scalable GraphQL APIs in a couple of simple steps - with only the GraphQL object types from your schema.

**What is Dgraph GraphQL?**

[Dgraph](https://dgraph.io/) is an open-source, distributed, transactional, native GraphQL database. Last week, we released the GA version of [Dgraph 20.03.00](https://github.com/dgraph-io/dgraph/releases/tag/v20.03.0). It comes with GraphQL out of the box.

To get started with Dgraph GraphQL is extremely simple. Just compose a GraphQL schema containing types to represent the data requirements of your application and submit it to Dgraphs HTTP endpoint. No need to initiate the database. No schema mapping or layering.

Dgraph takes those types, prepares graph storage for them, and auto-generates a production-ready, scalable CRUD Graph API with Queries and Mutations instantly.

All of these in only two steps, without having to write any server-side code or having to run your GraphQL server.

**Step 1: Run Dgraph GraphQL**

Use Dgraph standalone image to run Dgraph for a quick start.

```
docker run -it -p 8080:8080 -p 9080:9080 -p 8000:8000 dgraph/standalone:v20.03.0

```

**Step 2: Submit your schema to Dgraph GraphQL**

Save the GraphQL schema with your GraphQL types in a file, we're calling it schema.graphql. Don't bother adding the Query and Mutations types, Dgraph GraphQL auto-generates it for you.

```
type BlogPost {
  id: ID!
  title: String!
  content: String!
  hasAuthor: Author!
}
type Author {
  id: ID!
  name: String!
  hasBlog: [BlogPost]
}

```

Upload the schema to Dgraph GraphQL HTTP endpoint

```
curl -X POST localhost:8080/admin/schema -d '@schema.graphql'

```

That's it! You now have a production-ready, scalable GraphQL API!

Point your favorite GraphQL client to [http://localhost:8080/graphql](http://localhost:8080/graphql) and start using it!

## Conclusion

In this blog post, you learned an intuitive approach to design your GraphQL schema and some of the GraphQL types defined by the Schema Definition Language (SDL).

In the upcoming articles, we will show you how to compose a GraphQL schema and obtain functional GraphQL API for more complex UIs.

Subscribe to our email list so you will receive the article directly in your inbox. Until then, keep building smarter apps!

* * *
This is a companion discussion topic for the original entry at [https://dgraph.io/blog/post/designing-graphql-schemas/](https://dgraph.io/blog/post/designing-graphql-schemas/)

---

<div class="post-metadata">

**Author:** ![ctwhome](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/ctwhome/32/2634_2.png) [@ctwhome](https://discuss.dgraph.io/u/ctwhome)\
**Post date:** [April 13, 2020, 8:11pm UTC](https://discuss.dgraph.io/t/designing-graphql-schemas-dgraph-blog/6301/2 "2020-04-13T20:11:22Z")

</div>

congrats for the post!  
I may ask, would it be in the future an example app with Vue.js where it is included reactivity, full text search and auth with some data providers like google and user/password? That’d be a killer full stack boilerplate out of the box.

thanks!

---

<div class="post-metadata">

**Author:** ![prashant-shahi](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/prashant-shahi/32/1921_2.png) [@prashant-shahi](https://discuss.dgraph.io/u/prashant-shahi)\
**Post date:** [April 14, 2020, 12:31pm UTC](https://discuss.dgraph.io/t/designing-graphql-schemas-dgraph-blog/6301/3 "2020-04-14T12:31:45Z")

</div>

Hi @ctwhome,

We are currently working on building GraphQL example apps with Vue.js as well.

Stay tuned! 🙂

---

<div class="post-metadata">

**Author:** ![deepakrkpa](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/deepakrkpa/32/2762_2.png) [@deepakrkpa](https://discuss.dgraph.io/u/deepakrkpa)\
**Post date:** [April 23, 2020, 3:58pm UTC](https://discuss.dgraph.io/t/designing-graphql-schemas-dgraph-blog/6301/4 "2020-04-23T15:58:38Z")

</div>

Good post. Thanks for details. I am new to graphql and dgraph.  
create the below schema using CURL on /admin endpoint.  
type User {  
userID: ID!  
name: String  
email: String!  
address: String  
}  
I am able to add new user, able to display detail of single user passing ID but not able to edit user.  
I am not able to find any mutation that explain updateUser type in example.  
The schema shows mutation format as below:  
updateUser(input: UpdateUserInput!):UpdateUserPaylod  
but I am not able to figure out this.

---

<div class="post-metadata">

**Author:** ![deepakrkpa](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/deepakrkpa/32/2762_2.png) [@deepakrkpa](https://discuss.dgraph.io/u/deepakrkpa)\
**Post date:** [April 23, 2020, 4:00pm UTC](https://discuss.dgraph.io/t/designing-graphql-schemas-dgraph-blog/6301/5 "2020-04-23T16:00:12Z")

</div>

one more info I am building front end using vue apollo not using any server side code.

---

<div class="post-metadata">

**Author:** ![vardhanapoorv](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/vardhanapoorv/32/2441_2.png) [@vardhanapoorv](https://discuss.dgraph.io/u/vardhanapoorv)\
**Post date:** [April 23, 2020, 4:26pm UTC](https://discuss.dgraph.io/t/designing-graphql-schemas-dgraph-blog/6301/6 "2020-04-23T16:26:52Z")

</div>

Hi Deepak  
Are you facing issue in forming the object `UpdateUserInput`? The UpdateUserInput will look something like this - `{set: {name: "Deepak"}}` you can have more fields there. Making the mutation like -

```auto
mutation {
  updateUser(input:{filter:{userID: ["0x1d4c1"]} set: {name: "Deepak"}}) {
    user {
      name
    }
  }
}

```

When you introspect the schema you see the mutations and queries there and also the object that the mutation expects. Let me know if you have any more doubts.

---

<div class="post-metadata">

**Author:** ![deepakrkpa](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/deepakrkpa/32/2762_2.png) [@deepakrkpa](https://discuss.dgraph.io/u/deepakrkpa)\
**Post date:** [April 23, 2020, 4:45pm UTC](https://discuss.dgraph.io/t/designing-graphql-schemas-dgraph-blog/6301/7 "2020-04-23T16:45:28Z")

</div>

Thank you so much. Thats what I wanted.  
I also just figured out:

```auto
mutation updateUser ($id: ID!, $city: String!){
  updateUser (input: {filter:{userID:[$id]}, set:{city:$city}}) {
    user{
      userID
      city
    }
  }
}

```

and passing variable:  
{  
“id”: “”,  
“city”: “”  
}

---

<div class="post-metadata">

**Author:** ![deepakrkpa](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/deepakrkpa/32/2762_2.png) [@deepakrkpa](https://discuss.dgraph.io/u/deepakrkpa)\
**Post date:** [April 23, 2020, 4:48pm UTC](https://discuss.dgraph.io/t/designing-graphql-schemas-dgraph-blog/6301/8 "2020-04-23T16:48:27Z")

</div>

what if I want to pass a set of variables like:

“user”: {  
“city”: some new value,  
“other field”: some new value,  
}  
and pass all in set:{}

---

<div class="post-metadata">

**Author:** ![vardhanapoorv](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/vardhanapoorv/32/2441_2.png) [@vardhanapoorv](https://discuss.dgraph.io/u/vardhanapoorv)\
**Post date:** [April 23, 2020, 5:11pm UTC](https://discuss.dgraph.io/t/designing-graphql-schemas-dgraph-blog/6301/9 "2020-04-23T17:11:00Z")

</div>

You can modify your `set` to match that object if you don’t want to pass each variable separately. So something like this -

```auto
mutation updateUser($id: ID!, $user: UserPatch) {
  updateUser(input: {filter: {userID: [$id]}, set: $user}) {
    user {
      userID
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![deepakrkpa](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/deepakrkpa/32/2762_2.png) [@deepakrkpa](https://discuss.dgraph.io/u/deepakrkpa)\
**Post date:** [April 23, 2020, 5:55pm UTC](https://discuss.dgraph.io/t/designing-graphql-schemas-dgraph-blog/6301/10 "2020-04-23T17:55:40Z")

</div>

Thanks. I will try this with complete UI code.
