后端预制菜 - GraphQL

Posted by Hilalum on December 10, 2024 · 35 mins read

在现代软件开发中,API设计就像是后厨的菜谱,为前端应用(服务员)提供美食,供食客享用。

然而,在传统的RESTAPI模式下,我们常常面临一些困扰:

  • 数据“过度获取”或“不足获取”问题频繁出现;
  • 接口的设计和维护需要大量重复劳动;
  • 多端(Web、Mobile等)需要不同的数据格式,导致接口难以统一。

而GraphQL 的诞生,正如后端使用预制菜模式,为开发者提供了一种灵活高效的API查询方式。本文将带你初步了解GraphQL的核心理念和基本使用方式。

什么是GraphQL?

GraphQL是一种用于API的查询语言(Query Language),由Facebook在2015年开源。它的目标是让客户端能够精确获取所需的数据,同时简化API的设计和维护。GraphQL的核心思想可以总结为:你问什么,就返回什么

用一句话概括:GraphQL让客户端驱动数据查询,服务端仅提供能力,而非具体的数据形态。

GraphQL 的核心概念

Schema(预制菜)

GraphQL API的核心是Schema,它定义了数据模型和关系。可以理解为数据的蓝图,告诉客户端“后厨”有什么菜品,以及这些菜品由什么组成。 例如,一个简单的Schema可能是这样的:

    type Query {
        product(id: ID!): Product
        products: [Product]
    }

    type Product {
        id: ID!
        name: String!
        price: Float!
    }

其中:

  • Query是入口点,定义了客户端可以查询的内容。
  • Product是一个对象类型,表示商品的属性。

Query(菜单)

客户端通过Query查询数据。它像是点菜单,明确告诉服务端需要哪些数据。 例如:

    query GetProduct {
        product(id: "123") {
            name
            price
        }
    }

返回的数据是客户端请求的精确内容:

    {
        "data": {
            "product": {
            "name": "GraphQL Handbook",
            "price": 29.99
            }
        }
    }

Mutation

除了获取数据,GraphQL还支持通过Mutation修改数据,类似Rest中的增删改。

    mutation AddProduct {
        addProduct(name: "GraphQL Handbook", price: 29.99) {
            id
            name
        }
    }

Subscription(订阅)

GraphQL还支持实时数据更新,通过Subscription,可以监听数据的变化,适合构建聊天、通知等实时应用。

GraphQL相较REST的优势

  • 数据精确获取

GraphQL提供了一个灵活的查询机制,客户端可以根据需要获取数据,避免REST中的“过度获取”或“不足获取”。

  • 强类型系统

GraphQL的Schema提供了静态类型支持,开发者可以通过工具直接验证API,减少运行时错误。

  • 单一入口点

所有的请求通过单一URL进行处理,接口不会因需求变化而变得臃肿。

  • 更高的效率

在GraphQL中,一个查询可以替代多个REST请求,减少客户端和服务端的通信成本。

使用 GraphQL 的典型场景

  • 数据复杂的应用:需要多表关联的数据查询时,GraphQL的嵌套查询显得非常自然。
  • 多端开发:前端(Web、Mobile)对数据的需求不同,GraphQL可以根据客户端需求定制返回的数据。
  • 实时更新:例如股票行情、聊天应用,通过Subscription提供实时推送。

一个简单的 GraphQL 实现

假设我们正在构建一个“预制菜”电商平台后端,下面是一个用Node.js和Apollo Server实现的简单 GraphQL 服务:

安装依赖

npm install graphql apollo-server

编写代码

    const { ApolloServer, gql } = require('apollo-server');

    // Schema 定义
    const typeDefs = gql`
        type Query {
            product(id: ID!): Product
            products: [Product]
        }

        type Product {
            id: ID!
            name: String!
            price: Float!
        }
    `;

    // 模拟数据
    const products = [
        { id: "1", name: "Mapo Tofu Kit", price: 12.99 },
        { id: "2", name: "Kung Pao Chicken Kit", price: 15.99 },
    ];

    // Resolver 定义
    const resolvers = {
        Query: {
            product: (_, { id }) => products.find((p) => p.id === id),
            products: () => products,
        },
    };

    // 创建服务
    const server = new ApolloServer({ typeDefs, resolvers });

    server.listen().then(({ url }) => {
        console.log(`🚀 Server ready at ${url}`);
    });

总结

GraphQL的出现,为后端开发提供了“预制菜”式的便利,使数据查询变得更高效灵活。通过其强大的查询语言、灵活的数据结构和强大的工具生态,GraphQL正成为现代 API 设计的首选方案之一,特别是在国际化公司。如果你的项目面临多端数据需求复杂、接口变更频繁的问题,不妨试试GraphQL,说不定它正是你的“理想菜谱”!