自学内容网 自学内容网

现代Web开发:GraphQL入门指南

💓 博客主页:瑕疵的CSDN主页
📝 Gitee主页:瑕疵的gitee主页
⏩ 文章专栏:《热点资讯》

现代Web开发:GraphQL入门指南

引言

GraphQL 是一种用于 API 的查询语言,它提供了一种更有效和强大的方式来获取数据。与传统的 RESTful API 相比,GraphQL 允许客户端精确地请求所需的数据,减少了过度获取和不足获取的问题。本文将详细介绍 GraphQL 的基本概念、安装配置、核心功能以及实际应用,帮助读者快速上手 GraphQL 开发。

GraphQL 概述

什么是 GraphQL

GraphQL 是一种用于 API 的查询语言,它提供了一种标准的方式来请求和操作数据。GraphQL 由 Facebook 开发并于 2015 年开源,现已广泛应用于各种规模的项目中。

GraphQL 的特点

  • 强类型系统:GraphQL 使用强类型系统来定义数据模型,确保数据的一致性和可靠性。
  • 单一入口点:GraphQL API 通常只有一个入口点,客户端通过这个入口点发送查询请求。
  • 灵活的数据获取:客户端可以精确地请求所需的数据,减少不必要的数据传输。
  • 实时数据:GraphQL 支持订阅模式,可以实现实时数据更新。

安装和配置 GraphQL

安装 GraphQL

GraphQL 可以通过 npm(Node.js 包管理器)安装。

npm install graphql express-graphql

创建 GraphQL 服务器

使用 Express 和 express-graphql 创建一个简单的 GraphQL 服务器。

  1. 创建一个新的 Node.js 项目并初始化。
mkdir graphql-example
cd graphql-example
npm init -y
  1. 安装必要的依赖。
npm install express express-graphql graphql
  1. 创建 server.js 文件并编写以下代码。
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');

// 构建 GraphQL 模式
const schema = buildSchema(`
  type Query {
    hello: String
  }
`);

// 根解析器
const root = {
  hello: () => 'Hello, world!',
};

const app = express();

app.use('/graphql', graphqlHTTP({
  schema,
  rootValue: root,
  graphiql: true, // 启用 GraphiQL IDE
}));

app.listen(4000, () => {
  console.log('Running a GraphQL API server at http://localhost:4000/graphql');
});
  1. 启动服务器。
node server.js

验证安装

启动服务器后,打开浏览器并访问 http://localhost:4000/graphql,你会看到 GraphiQL IDE。在查询窗口中输入以下查询并执行:

query {
  hello
}

你应该会看到如下响应:

{
  "data": {
    "hello": "Hello, world!"
  }
}

GraphQL 基础

构建模式

GraphQL 模式定义了 API 的结构,包括可用的查询、变更和订阅。

定义查询
const schema = buildSchema(`
  type Query {
    book(id: ID!): Book
    books: [Book]
  }

  type Book {
    id: ID!
    title: String
    author: String
  }
`);

const root = {
  book: ({ id }) => books.find(book => book.id === id),
  books: () => books,
};

const books = [
  { id: '1', title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
  { id: '2', title: 'To Kill a Mockingbird', author: 'Harper Lee' },
];
定义变更
const schema = buildSchema(`
  type Query {
    book(id: ID!): Book
    books: [Book]
  }

  type Mutation {
    addBook(title: String!, author: String!): Book
  }

  type Book {
    id: ID!
    title: String
    author: String
  }
`);

const root = {
  book: ({ id }) => books.find(book => book.id === id),
  books: () => books,
  addBook: ({ title, author }) => {
    const id = books.length + 1;
    const book = { id, title, author };
    books.push(book);
    return book;
  },
};

const books = [
  { id: '1', title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
  { id: '2', title: 'To Kill a Mockingbird', author: 'Harper Lee' },
];

查询和变更

查询
query {
  book(id: "1") {
    id
    title
    author
  }
}
变更
mutation {
  addBook(title: "1984", author: "George Orwell") {
    id
    title
    author
  }
}

参数和变量

GraphQL 支持参数和变量,使查询更加灵活。

参数
query {
  book(id: "1") {
    id
    title
    author
  }
}
变量
query GetBook($id: ID!) {
  book(id: $id) {
    id
    title
    author
  }
}

variables:
{
  "id": "1"
}

分辨器

分辨器是处理查询和变更的函数,负责从数据源中获取数据。

const root = {
  book: ({ id }) => books.find(book => book.id === id),
  books: () => books,
  addBook: ({ title, author }) => {
    const id = books.length + 1;
    const book = { id, title, author };
    books.push(book);
    return book;
  },
};

GraphQL 高级功能

分页

分页是处理大量数据的一种常见方法,GraphQL 提供了灵活的分页机制。

const schema = buildSchema(`
  type Query {
    books(page: Int!, pageSize: Int!): [Book]
  }

  type Book {
    id: ID!
    title: String
    author: String
  }
`);

const root = {
  books: ({ page, pageSize }) => {
    const startIndex = (page - 1) * pageSize;
    const endIndex = startIndex + pageSize;
    return books.slice(startIndex, endIndex);
  },
};

const books = [
  { id: '1', title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
  { id: '2', title: 'To Kill a Mockingbird', author: 'Harper Lee' },
  { id: '3', title: '1984', author: 'George Orwell' },
  { id: '4', title: 'Brave New World', author: 'Aldous Huxley' },
];

订阅

订阅用于实现实时数据更新,通常与 WebSocket 一起使用。

const { PubSub } = require('graphql-subscriptions');
const pubsub = new PubSub();
const NEW_BOOK_ADDED = 'NEW_BOOK_ADDED';

const schema = buildSchema(`
  type Query {
    book(id: ID!): Book
    books: [Book]
  }

  type Mutation {
    addBook(title: String!, author: String!): Book
  }

  type Subscription {
    newBookAdded: Book
  }

  type Book {
    id: ID!
    title: String
    author: String
  }
`);

const root = {
  book: ({ id }) => books.find(book => book.id === id),
  books: () => books,
  addBook: ({ title, author }) => {
    const id = books.length + 1;
    const book = { id, title, author };
    books.push(book);
    pubsub.publish(NEW_BOOK_ADDED, { newBookAdded: book });
    return book;
  },
  newBookAdded: {
    subscribe: () => pubsub.asyncIterator([NEW_BOOK_ADDED]),
  },
};

const books = [
  { id: '1', title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
  { id: '2', title: 'To Kill a Mockingbird', author: 'Harper Lee' },
];

错误处理

GraphQL 提供了统一的错误处理机制,可以在分辨器中抛出错误。

const root = {
  book: ({ id }) => {
    const book = books.find(book => book.id === id);
    if (!book) {
      throw new Error('Book not found');
    }
    return book;
  },
  books: () => books,
  addBook: ({ title, author }) => {
    if (!title || !author) {
      throw new Error('Title and author are required');
    }
    const id = books.length + 1;
    const book = { id, title, author };
    books.push(book);
    return book;
  },
};

实战案例分析

简单的图书管理系统

假设我们要构建一个简单的图书管理系统,包含图书的增删改查功能。

项目结构
book-manager/
├── models/
│   └── book.js
├── resolvers/
│   └── book.js
├── schema/
│   └── book.graphql
├── server.js
├── package.json
└── README.md
安装依赖
npm install express express-graphql graphql graphql-tools graphql-yoga
定义模式

schema/book.graphql 中定义模式。

scalar DateTime

type Book {
  id: ID!
  title: String!
  author: String!
  publishedAt: DateTime!
}

type Query {
  book(id: ID!): Book
  books: [Book!]!
}

type Mutation {
  addBook(title: String!, author: String!, publishedAt: DateTime!): Book!
  updateBook(id: ID!, title: String, author: String, publishedAt: DateTime): Book
  deleteBook(id: ID!): Boolean!
}
定义模型

models/book.js 中定义模型。

const books = [
  { id: '1', title: 'The Great Gatsby', author: 'F. Scott Fitzgerald', publishedAt: '1925-04-10T00:00:00Z' },
  { id: '2', title: 'To Kill a Mockingbird', author: 'Harper Lee', publishedAt: '1960-07-11T00:00:00Z' },
];

module.exports = { books };
定义解析器

resolvers/book.js 中定义解析器。

const { books } = require('../models/book');

const resolvers = {
  Query: {
    book: (_, { id }) => books.find(book => book.id === id),
    books: () => books,
  },
  Mutation: {
    addBook: (_, { title, author, publishedAt }) => {
      const id = books.length + 1;
      const book = { id, title, author, publishedAt };
      books.push(book);
      return book;
    },
    updateBook: (_, { id, title, author, publishedAt }) => {
      const bookIndex = books.findIndex(book => book.id === id);
      if (bookIndex === -1) {
        throw new Error('Book not found');
      }
      const updatedBook = { ...books[bookIndex], title, author, publishedAt };
      books[bookIndex] = updatedBook;
      return updatedBook;
    },
    deleteBook: (_, { id }) => {
      const bookIndex = books.findIndex(book => book.id === id);
      if (bookIndex === -1) {
        throw new Error('Book not found');
      }
      books.splice(bookIndex, 1);
      return true;
    },
  },
};

module.exports = resolvers;
创建服务器

server.js 中创建 GraphQL 服务器。

const express = require('express');
const { ApolloServer } = require('apollo-server-express');
const typeDefs = require('./schema/book.graphql');
const resolvers = require('./resolvers/book');

const app = express();

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

server.applyMiddleware({ app, path: '/graphql' });

app.listen(4000, () => {
  console.log('Running a GraphQL API server at http://localhost:4000/graphql');
});

总结

通过本文,我们深入了解了 GraphQL 的基本概念、安装配置、核心功能以及实际应用。GraphQL 是一个强大的查询语言,适用于构建高效和灵活的 API。希望本文能帮助读者更好地理解和应用 GraphQL,提升Web开发能力。
GraphQL架构图

参考资料


原文地址:https://blog.csdn.net/qq_36287830/article/details/143605585

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!