GRAPH SQL tutorial with examples

 

GraphQL Tutorial with Examples

GraphQL is a query language for APIs and a runtime for executing queries by defining a schema. It provides a more flexible and efficient alternative to RESTful APIs, allowing clients to request exactly the data they need, and nothing more. GraphQL works over a single endpoint, typically using HTTP or WebSockets, and can return structured data as requested by the client.

Here’s an introductory tutorial to help you get started with GraphQL, including its core concepts, how to create a GraphQL API, and some practical examples.


1. Key Concepts of GraphQL:

  • Schema: Defines the structure of the data and operations (queries, mutations, subscriptions).
  • Query: A request to fetch data. It is like a GET request in REST APIs.
  • Mutation: A request to modify data (e.g., create, update, or delete data). It is similar to POST, PUT, or DELETE in REST.
  • Subscription: A real-time connection to the server to receive updates (usually used for live data or notifications).
  • Resolver: Functions that provide instructions for turning a GraphQL operation into data. A resolver is responsible for fetching or updating data when a query or mutation is executed.

2. GraphQL Basics

Let’s first look at a basic example of a GraphQL query and how it interacts with data.

GraphQL Schema Definition

Here’s a simple GraphQL schema where we have a Book type and a query to fetch a list of books.

graphql
# Define the Book type type Book { id: ID! title: String! author: String! yearPublished: Int } # Root Query: Fetch a list of books type Query { books: [Book] book(id: ID!): Book }
  • Book type defines a book object with id, title, author, and yearPublished fields.
  • The Query type defines two queries:
    • books: Returns a list of books.
    • book: Returns a single book by its id.

3. GraphQL Queries

Let’s see how to query this schema. You send a query to request data from the server.

Example Query: Fetch all books

graphql
query { books { id title author yearPublished } }

This query asks for the id, title, author, and yearPublished of all books in the database. The server will respond with the requested data.

Example Query: Fetch a specific book by ID

graphql
query { book(id: "1") { title author yearPublished } }

In this case, we’re asking for details of a specific book with the id of 1. The query response will only contain the fields we ask for.


4. GraphQL Mutations

Mutations are used to modify data (insert, update, delete). Here’s an example of how to define a mutation.

GraphQL Mutation Schema:

graphql
# Mutation to add a new book type Mutation { addBook(title: String!, author: String!, yearPublished: Int): Book }
  • The mutation addBook will take parameters title, author, and yearPublished to create a new book.

Example Mutation: Adding a new book

graphql
mutation { addBook(title: "The Great Gatsby", author: "F. Scott Fitzgerald", yearPublished: 1925) { id title author yearPublished } }

Here, we’re sending a mutation to add a book. The server will return the newly created book, including its id (which is typically auto-generated).


5. GraphQL Resolvers

Resolvers are functions that resolve the queries and mutations by fetching data. They implement the actual business logic.

For example, in a Node.js server using Apollo Server (a popular GraphQL implementation), you can define resolvers like this:

js
const resolvers = { Query: { books: () => { return booksData; // fetch books from a data source }, book: (parent, args) => { return booksData.find(book => book.id === args.id); // fetch a specific book }, }, Mutation: { addBook: (parent, args) => { const newBook = { id: booksData.length + 1, // simple ID generation title: args.title, author: args.author, yearPublished: args.yearPublished, }; booksData.push(newBook); // add the book to the list return newBook; // return the newly added book }, }, };
  • Resolvers map directly to the fields defined in the schema.
  • The addBook mutation receives the arguments (title, author, yearPublished), processes them, and returns a new book object.

6. Setting Up a Basic GraphQL Server with Apollo Server (Node.js)

Let’s walk through how to set up a basic GraphQL server using Apollo Server in a Node.js environment.

Step 1: Install dependencies

First, you’ll need to install the required packages:

bash
npm init -y npm install apollo-server graphql

Step 2: Define the Schema and Resolvers

Create a file named server.js with the following content:

js
const { ApolloServer, gql } = require('apollo-server'); // Sample book data const booksData = [ { id: '1', title: '1984', author: 'George Orwell', yearPublished: 1949 }, { id: '2', title: 'To Kill a Mockingbird', author: 'Harper Lee', yearPublished: 1960 }, ]; // GraphQL Schema const typeDefs = gql` type Book { id: ID! title: String! author: String! yearPublished: Int } type Query { books: [Book] book(id: ID!): Book } type Mutation { addBook(title: String!, author: String!, yearPublished: Int): Book } `; // Resolvers to fetch data const resolvers = { Query: { books: () => booksData, book: (parent, args) => booksData.find(book => book.id === args.id), }, Mutation: { addBook: (parent, args) => { const newBook = { id: (booksData.length + 1).toString(), title: args.title, author: args.author, yearPublished: args.yearPublished, }; booksData.push(newBook); return newBook; }, }, }; // Apollo Server Setup const server = new ApolloServer({ typeDefs, resolvers }); // Start the server server.listen().then(({ url }) => { console.log(`Server is running at ${url}`); });

Step 3: Run the Server

Start the server with Node.js:

bash
node server.js

The server will run at http://localhost:4000/. You can interact with the GraphQL API using the built-in GraphQL Playground interface that Apollo Server provides.


7. GraphQL Subscriptions (Real-time Data)

GraphQL subscriptions allow you to receive real-time data updates. They work over WebSocket, and you can use them to subscribe to events such as new data being added or updated.

Here’s a simple example:

graphql
type Subscription { bookAdded: Book }

Implementation Example (using Apollo Server):

js
const { PubSub } = require('graphql-subscriptions'); const pubsub = new PubSub(); // Mutation to trigger subscription Mutation: { addBook: (parent, args) => { const newBook = { id: booksData.length + 1, title: args.title, author: args.author, yearPublished: args.yearPublished, }; booksData.push(newBook); pubsub.publish('BOOK_ADDED', { bookAdded: newBook }); // Notify subscribers return newBook; }, }, // Subscription to listen for new books Subscription: { bookAdded: { subscribe: () => pubsub.asyncIterator('BOOK_ADDED'), }, },

This will allow clients to subscribe to updates when a new book is added.


8. Example Client for GraphQL (Using Apollo Client)

Here’s how you might interact with a GraphQL API from the client-side (using Apollo Client in a React app):

Install Apollo Client

bash
npm install @apollo/client graphql

Client-side Example (React):

js
import React, { useEffect, useState } from 'react'; import { ApolloClient, InMemoryCache, gql, ApolloProvider, useQuery, useMutation } from '@apollo/client'; // Setup Apollo Client const client = new ApolloClient({ uri: 'http://localhost:4000/', cache: new InMemoryCache(), }); // GraphQL Query const GET_BOOKS = gql` query { books { id title author yearPublished } } `; // GraphQL Mutation const ADD_BOOK = gql` mutation addBook($title: String!, $author: String!, $yearPublished: Int) {
addBook(title: $title, author: $author, yearPublished: $yearPublished) { id title } } `; // React Component to Display Books const BooksList = () => { const { data, loading, error } = useQuery(GET_BOOKS); if (loading) return <p>Loading...</p>; if (error) return <p>Error loading books</p>; return ( <div> <h3>Books List</h3> {data.books.map(book => ( <div key={book.id}> <p>{book.title} by {book.author}</p> </div> ))} </div> ); }; // React Component to Add Books const AddBookForm = () => { const [title, setTitle] = useState(''); const [author, setAuthor] = useState(''); const [yearPublished, setYearPublished] = useState(''); const [addBook] = useMutation(ADD_BOOK); const handleSubmit = async (e) => { e.preventDefault(); await addBook({ variables: { title, author, yearPublished: parseInt(yearPublished) } }); setTitle(''); setAuthor(''); setYearPublished(''); }; return ( <form onSubmit={handleSubmit}> <input type="text" placeholder="Title" value={title} onChange={e => setTitle(e.target.value)} /> <input type="text" placeholder="Author" value={author} onChange={e => setAuthor(e.target.value)} /> <input type="number" placeholder="Year" value={yearPublished} onChange={e => setYearPublished(e.target.value)} /> <button type="submit">Add Book</button> </form> ); }; function App() { return ( <ApolloProvider client={client}> <BooksList /> <AddBookForm /> </ApolloProvider> ); } export default App;

Conclusion

This tutorial introduced you to GraphQL, covering key concepts such as queries, mutations, subscriptions, resolvers, and schemas. It also showed how to set up a basic GraphQL server using Apollo Server and how to interact with a GraphQL API on the client side using Apollo Client.

GraphQL offers powerful ways to handle data fetching and manipulation, and with tools like Apollo Server and Apollo Client, building and consuming GraphQL APIs becomes much easier.

Comments

Popular posts from this blog

PrimeNG tutorial with examples using frequently used classes

Docker and Kubernetes Tutorials and QnA

oAuth in angular