{"id":4190,"date":"2023-11-04T23:14:07","date_gmt":"2023-11-04T23:14:07","guid":{"rendered":"http:\/\/localhost:10003\/building-apis-with-graphql\/"},"modified":"2023-11-05T05:47:58","modified_gmt":"2023-11-05T05:47:58","slug":"building-apis-with-graphql","status":"publish","type":"post","link":"http:\/\/localhost:10003\/building-apis-with-graphql\/","title":{"rendered":"Building APIs with GraphQL"},"content":{"rendered":"
APIs are a crucial part of modern software development. They allow different applications to communicate with each other, enabling a variety of functionalities such as data sharing, integration, and automation. Recently, GraphQL has gained traction as an alternative to traditional REST APIs. In this tutorial, we will learn how to build APIs with GraphQL and explore its advantages over REST.<\/p>\n
GraphQL is a query language developed by Facebook for building APIs. It provides a flexible and efficient mechanism for querying and manipulating data using a single endpoint. With GraphQL, clients can specify exactly what data they need, and the server responds with only that data.<\/p>\n
GraphQL also supports real-time updates using subscriptions. Clients can subscribe to certain data and receive updates whenever that data changes on the server. This makes GraphQL ideal for applications that require real-time data such as chat applications and gaming platforms.<\/p>\n
Before we start building our GraphQL API, we need to install some tools and frameworks. Here are the prerequisites for this tutorial:<\/p>\n
You can install Node.js and npm from their website. Once you have installed Node.js and npm, you can install the remaining packages using the following command:<\/p>\n
npm install express graphql nodemon body-parser\n<\/code><\/pre>\nGetting Started<\/h2>\n
Let’s start by creating a new directory for our project and initializing a new Node.js project:<\/p>\n
mkdir graphql-api\ncd graphql-api\nnpm init -y\n<\/code><\/pre>\nThis will create a new project with a package.json file that we can use to manage our dependencies. Next, let’s create a new file called server.js<\/code> and add the following code:<\/p>\nconst express = require('express')\nconst { graphqlHTTP } = require('express-graphql')\nconst { buildSchema } = require('graphql')\nconst bodyParser = require('body-parser')\n\nconst app = express()\n\napp.use(bodyParser.json())\n\nconst schema = buildSchema(`\n type Query {\n hello: String\n }\n`)\n\nconst root = {\n hello: () => 'Hello World!'\n}\n\napp.use('\/graphql', graphqlHTTP({\n schema,\n rootValue: root,\n graphiql: true\n}))\n\nconst port = process.env.PORT || 4000\n\napp.listen(port, () => console.log(`GraphQL API running on port ${port}`))\n<\/code><\/pre>\nLet’s break down this code. First, we import the necessary packages: express<\/code>, express-graphql<\/code>, graphql<\/code>, and body-parser<\/code>. We use express<\/code> to create a new instance of an Express application. Then, we use body-parser<\/code> to parse incoming JSON requests.<\/p>\nNext, we define our GraphQL schema using the buildSchema<\/code> function from the graphql<\/code> package. Our schema has a single query field called hello<\/code> that returns a string.<\/p>\nWe also define a resolver object called root<\/code> that maps to the schema. The hello<\/code> resolver returns the string “Hello World!”.<\/p>\nFinally, we use express-graphql<\/code> to create a new GraphQL endpoint at \/graphql<\/code>. We pass in our schema and resolver object as options to graphqlHTTP<\/code>. We also set graphiql<\/code> to true<\/code>, which enables the GraphiQL IDE for testing our API.<\/p>\nWe start our server on port 4000 using the listen<\/code> method from our Express application.<\/p>\nTo start our server, run nodemon server.js<\/code> in your terminal. You should see a message that says “GraphQL API running on port 4000”. Open your browser and navigate to `http:\/\/localhost:4000\/graphql`. You should see the GraphiQL IDE. In the left panel, type:<\/p>\n{\n hello\n}\n<\/code><\/pre>\nThen, click the play button in the top left corner. You should see the response:<\/p>\n
{\n \"data\": {\n \"hello\": \"Hello World!\"\n }\n}\n<\/code><\/pre>\nCongratulations! You have just created your first GraphQL API.<\/p>\n
Adding Data Sources<\/h2>\n
Now that we have a basic GraphQL API, let’s add some data sources. In this tutorial, we will use fake data to keep things simple. We will create an array of books and authors and expose them through our API.<\/p>\n
First, let’s add the data to our server.js<\/code> file:<\/p>\nconst books = [\n {\n id: 'book-1',\n title: 'Harry Potter and the Philosopher's Stone',\n authorId: 'author-1'\n },\n {\n id: 'book-2',\n title: 'Harry Potter and the Chamber of Secrets',\n authorId: 'author-1'\n },\n {\n id: 'book-3',\n title: 'Harry Potter and the Prisoner of Azkaban',\n authorId: 'author-1'\n },\n {\n id: 'book-4',\n title: 'The Hobbit',\n authorId: 'author-2'\n },\n {\n id: 'book-5',\n title: 'The Lord of the Rings',\n authorId: 'author-2'\n }\n]\n\nconst authors = [\n {\n id: 'author-1',\n name: 'J.K. Rowling'\n },\n {\n id: 'author-2',\n name: 'J.R.R. Tolkien'\n }\n]\n<\/code><\/pre>\nNext, let’s update our schema and resolver object to include the new data:<\/p>\n
const schema = buildSchema(`\n type Query {\n book(id: ID!): Book\n books: [Book]\n author(id: ID!): Author\n authors: [Author]\n }\n\n type Book {\n id: ID!\n title: String!\n author: Author!\n }\n\n type Author {\n id: ID!\n name: String!\n books: [Book]\n }\n`)\n\nconst root = {\n book: ({ id }) => books.find(book => book.id === id),\n books: () => books,\n author: ({ id }) => authors.find(author => author.id === id),\n authors: () => authors,\n Book: {\n author: (book) => authors.find(author => author.id === book.authorId)\n },\n Author: {\n books: (author) => books.filter(book => book.authorId === author.id)\n }\n}\n<\/code><\/pre>\nWe have added four new fields to our schema: book<\/code>, books<\/code>, author<\/code>, and authors<\/code>. Each of these fields has a corresponding resolver function that returns the appropriate data from our arrays.<\/p>\nWe have also updated the Book<\/code> and Author<\/code> types to include their relationships to the other type. The author<\/code> field on Book<\/code> returns the author object for that book, and the books<\/code> field on Author<\/code> returns an array of the books that author has written.<\/p>\nWe also need to update our query. In the left panel of the GraphiQL IDE, type:<\/p>\n
{\n books {\n id\n title\n author {\n name\n }\n }\n}\n<\/code><\/pre>\nThen, click the play button. You should see a response that looks like this:<\/p>\n
{\n \"data\": {\n \"books\": [\n {\n \"id\": \"book-1\",\n \"title\": \"Harry Potter and the Philosopher's Stone\",\n \"author\": {\n \"name\": \"J.K. Rowling\"\n }\n },\n {\n \"id\": \"book-2\",\n \"title\": \"Harry Potter and the Chamber of Secrets\",\n \"author\": {\n \"name\": \"J.K. Rowling\"\n }\n },\n {\n \"id\": \"book-3\",\n \"title\": \"Harry Potter and the Prisoner of Azkaban\",\n \"author\": {\n \"name\": \"J.K. Rowling\"\n }\n },\n {\n \"id\": \"book-4\",\n \"title\": \"The Hobbit\",\n \"author\": {\n \"name\": \"J.R.R. Tolkien\"\n }\n },\n {\n \"id\": \"book-5\",\n \"title\": \"The Lord of the Rings\",\n \"author\": {\n \"name\": \"J.R.R. Tolkien\"\n }\n }\n ]\n }\n}\n<\/code><\/pre>\nCongratulations! You have just added data sources to your GraphQL API.<\/p>\n
Mutations<\/h2>\n
So far, we have only used queries to fetch data from our API. However, GraphQL also provides mutations, which allow us to modify data. In this section, we will learn how to write mutations in GraphQL.<\/p>\n
Let’s add a mutation to our schema that allows us to add new books:<\/p>\n
const schema = buildSchema(`\n type Query {\n book(id: ID!): Book\n books: [Book]\n author(id: ID!): Author\n authors: [Author]\n }\n\n type Mutation {\n addBook(title: String!, authorId: ID!): Book\n }\n\n type Book {\n id: ID!\n title: String!\n author: Author!\n }\n\n type Author {\n id: ID!\n name: String!\n books: [Book]\n }\n`)\n<\/code><\/pre>\nWe have added a new field to our schema called Mutation<\/code>. This field has a single resolver function called addBook<\/code>, which takes in a title<\/code> and authorId<\/code> and returns the new book object. We have also updated the Book<\/code> and Author<\/code> types to include the id<\/code> field, which is required for mutations.<\/p>\nNext, let’s update our resolver object to include the addBook<\/code> function:<\/p>\nconst root = {\n book: ({ id }) => books.find(book => book.id === id),\n books: () => books,\n author: ({ id }) => authors.find(author => author.id === id),\n authors: () => authors,\n Book: {\n author: (book) => authors.find(author => author.id === book.authorId)\n },\n Author: {\n books: (author) => books.filter(book => book.authorId === author.id)\n },\n addBook: ({ title, authorId }) => {\n const id = `book-${books.length + 1}`\n const book = { id, title, authorId }\n books.push(book)\n return book\n }\n}\n<\/code><\/pre>\nOur addBook<\/code> resolver function takes in title<\/code> and authorId<\/code> arguments and generates a new id<\/code> for the book. It then creates a new object for the book and adds it to the books<\/code> array. Finally, it returns the new book object.<\/p>\nTo test our mutation, in the left panel of the GraphiQL IDE, type:<\/p>\n
mutation {\n addBook(title: \"The Silmarillion\", authorId: \"author-2\") {\n id\n title\n author {\n name\n }\n }\n}\n<\/code><\/pre>\nThen, click the play button. You should see a response that looks similar to this:<\/p>\n
{\n \"data\": {\n \"addBook\": {\n \"id\": \"book-6\",\n \"title\": \"The Silmarillion\",\n \"author\": {\n \"name\": \"J.R.R. Tolkien\"\n }\n }\n }\n}\n<\/code><\/pre>\nCongratulations! You have just written your first mutation.<\/p>\n
Subscriptions<\/h2>\n
In addition to queries and mutations, GraphQL also provides subscriptions, which allow clients to subscribe to real-time updates from the server. In this section, we will learn how to write subscriptions in GraphQL.<\/p>\n
Let’s add a subscription to our schema that allows clients to receive updates whenever a new book is added:<\/p>\n
const schema = buildSchema(`\n type Query {\n book(id: ID!): Book\n books: [Book]\n author(id: ID!): Author\n authors: [Author]\n }\n\n type Mutation {\n addBook(title: String!, authorId: ID!): Book\n }\n\n type Subscription {\n newBook: Book\n }\n\n type Book {\n id: ID!\n title: String!\n author: Author!\n }\n\n type Author {\n id: ID!\n name: String!\n books: [Book]\n }\n`)\n<\/code><\/pre>\nWe have added a new field to our schema called Subscription<\/code>. This field has a single resolver function called newBook<\/code>, which returns the latest book added to our books<\/code> array.<\/p>\nNext, let’s update our resolver object to include the newBook<\/code> function:<\/p>\nconst root = {\n book: ({ id }) => books.find(book => book.id === id),\n books: () => books,\n author: ({ id }) => authors.find(author => author.id === id),\n authors: () => authors,\n Book: {\n author: (book) => authors.find(author => author.id === book.authorId)\n },\n Author: {\n books: (author) => books.filter(book => book.authorId === author.id)\n },\n addBook: ({ title, authorId }) => {\n const id = `book-${books.length + 1}`\n const book = { id, title, authorId }\n books.push(book)\n return book\n },\n newBook: (args, context) => {\n const latestBook = books[books.length - 1]\n return latestBook\n }\n}\n<\/code><\/pre>\nOur newBook<\/code> resolver function returns the latest book added to the books<\/code> array.<\/p>\nTo test our subscription, in the left panel of the GraphiQL IDE, type:<\/p>\n
subscription {\n newBook {\n id\n title\n author {\n name\n }\n }\n}\n<\/code><\/pre>\nThen, click the play button. You should see a message that says “Waiting for data…”. In a new tab, run the mutation we wrote earlier to add a new book:<\/p>\n
mutation {\n addBook(title: \"The Silmarillion\", authorId: \"author-2\") {\n id\n title\n author {\n name\n }\n }\n}\n<\/code><\/pre>\nIf everything is set up correctly, you should see a new message in the left panel that shows the latest book added to the books<\/code> array.<\/p>\nCongratulations! You have just written your first subscription.<\/p>\n
Conclusion<\/h2>\n
In this tutorial, we learned how to build a GraphQL API and explored its advantages over REST. We started by creating a basic GraphQL API with a single query field. We then added data sources using arrays of books and authors and updated our schema and resolver object to include these new fields.<\/p>\n
We also learned how to write mutations to modify data and subscriptions to receive real-time updates. With these tools, we can create powerful and flexible APIs that can adapt to a variety of use cases.<\/p>\n
Thank you for reading this tutorial, and I hope you found it helpful. With the knowledge gained here, you are equipped to build your own GraphQL APIs and take advantage of its powerful features.<\/p>\n","protected":false},"excerpt":{"rendered":"
APIs are a crucial part of modern software development. They allow different applications to communicate with each other, enabling a variety of functionalities such as data sharing, integration, and automation. Recently, GraphQL has gained traction as an alternative to traditional REST APIs. In this tutorial, we will learn how to Continue Reading<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[1],"tags":[926,407,457,406,1619,289],"yoast_head":"\nBuilding APIs with GraphQL - Pantherax Blogs<\/title>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\n\t\n\t\n