GraphQL is a query language for APIs and a runtime for executing those queries. Unlike traditional REST APIs, GraphQL allows clients to request exactly the data they need—nothing more, nothing less—optimizing the data fetching process. All requests are handled through a single endpoint, and clients can combine multiple resource queries into a single request, eliminating the need for multiple HTTP calls. GraphQL's flexibility and efficiency make it ideal for dynamic data structures and complex applications, especially when efficient data transfer and cross-platform interaction are required.
The schema defines the types of fields and the structure of the data. When you make an invalid operation, the GraphQL engine will tell you exactly where the problem is, with detailed error messages, making development and debugging very friendly.
GraphQL has built-in types like String, Int, Float, Boolean, and ID. You can also define your own types.
type User {
id: ID
email: String
image: String
role: Role
posts: [Post]
}
enum Role {
ADMIN
USER
}
type Post {
id: ID
category: String
description: String
title: String
likes: [User]
}
From the schema, you can see that an author can have multiple posts, and a post can have multiple users who like it.
To query all posts, use !
to indicate non-null. The syntax is almost the same as TypeScript.
// graphql/schema.ts
export const typeDefs = `
type Query {
posts: [Post]!
}
`
You can also query a specific post by its id:
// graphql/schema.ts
export const typeDefs = `
type Query {
post(id: ID!): Post!
}
`
Define mutations for creating, deleting, and updating posts:
// graphql/schema.ts
export const typeDefs = `
...
type Mutation {
createPost(category: String!, description: String!, title: String!): Post!
deletePost(id: ID!): Post!
updatePost(category: String, description: String, id: String, title: String): Post!
}
`
When the frontend sends a request to the backend, the corresponding resolver function provides the response data. For example, to query all posts, you can use Prisma to query the database:
// /graphql/resolvers.ts
import prisma from '../lib/prisma'
export const resolvers = {
Query: {
posts: () => {
return prisma.post.findMany()
},
},
}
pnpm add graphql graphql-yoga
graphql-yoga
is a popular GraphQL server framework with a built-in GraphQL Playground, making it convenient for developers to test and debug APIs. It's great for rapid development and learning.
// src/api/graphql/route.ts
import { createSchema, createYoga } from 'graphql-yoga'
import { resolvers } from '../../graphql/resolvers'
import { typeDefs } from '../../graphql/schema'
import { NextRequest } from 'next/server'
const { handleRequest } = createYoga({
schema: createSchema({
typeDefs,
resolvers,
}),
})
export async function GET(request: NextRequest) {
return handleRequest(request, {} as any)
}
export async function POST(request: NextRequest) {
return handleRequest(request, {} as any)
}
Now, run pnpm dev
and visit http://localhost:3000/api/graphql/
to see the GraphiQL Playground. Enter the following code to query the list of posts, specifying the id
and title
fields from the Post model:
query {
posts {
id
title
}
}