使用GraphQL构建现代API

news2024/11/5 16:28:25

使用GraphQL构建现代API

      • GraphQL简介
      • 安装GraphQL
        • 使用npm安装GraphQL
        • 使用Yarn安装GraphQL
      • 创建GraphQL服务器
      • 定义Schema
      • 编写Resolver
      • 查询数据
      • 变更数据
      • 使用Apollo Client
      • GraphQL订阅
      • 数据验证
      • 错误处理
      • 分页查询
      • 拆分和组合Schema
      • 总结

随着API的发展,传统的RESTful API逐渐显露出其局限性,特别是在需要灵活的数据查询和减少网络往返次数的应用场景中。GraphQL作为一种新兴的数据查询和操作语言,正好弥补了这一缺陷。本文将详细介绍如何使用GraphQL来构建现代API。

GraphQL简介

GraphQL是一种用于API的查询语言,它提供了一种更有效的方式去获取数据。

安装GraphQL

GraphQL通常通过GraphQL服务器和客户端库来使用。

使用npm安装GraphQL
如果项目使用Node.js,可以使用npm安装GraphQL。

npm install graphql graphql-yoga

使用Yarn安装GraphQL
如果项目使用Yarn,可以使用Yarn安装GraphQL。

yarn add graphql graphql-yoga

创建GraphQL服务器

使用graphql-yoga快速创建一个GraphQL服务器。
创建GraphQL服务器示例

const { GraphQLServer } = require('graphql-yoga');

const resolvers = {
  Query: {
    hello: () => 'Hello World!',
  },
};

const server = new GraphQLServer({ typeDefs, resolvers });
server.start(() => console.log('Server running on http://localhost:4000')); 

定义Schema

在GraphQL中,Schema定义了数据的结构和可用的操作。

type Query {
  hello: String
}

编写Resolver

Resolver负责执行具体的操作并返回数据。

const resolvers = {
  Query: {
    hello: () => 'Hello World!',
  },
};

查询数据

在GraphQL中,可以通过简单的查询语句来获取数据。

query {
  hello
}

变更数据

除了查询之外,GraphQL还支持变更数据的操作。

schema {
  query: Query
  mutation: Mutation
}

... existing schema ...

type Mutation {
  incrementCount: Int!
}
const resolvers = {
  ... existing resolvers ...
  Mutation: {
    incrementCount: (parent, args, context, info) => {
      context.count++;
      return context.count;
    }
  }
};
mutation {
  incrementCount
}

使用Apollo Client

Apollo Client是一个完整的状态管理库,专门为GraphQL打造。
使用Apollo Client示例

npm install @apollo/client
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:4000/',
  cache: new InMemoryCache(),
});

client.query({
  query: gql`{
    hello
  }`,
}).then(console.log);

GraphQL订阅

GraphQL不仅支持查询和变更数据,还支持订阅数据的变化。

subscription {
  countUpdated @subscription
}
const resolvers = {
  Subscription: {
    countUpdated: {
      subscribe: (parent, args, { pubsub }) => {
        return pubsub.asyncIterator('COUNT_UPDATED');
      }
    }
  }
};
const pubsub = new PubSub();

// Inside resolver that modifies the count
pubsub.publish('COUNT_UPDATED', { countUpdated: context.count });

数据验证

GraphQL提供了强大的类型系统来帮助开发者定义和验证数据。

type User {
  id: ID!
  name: String!
  email: String!
}
const resolvers = {
  Query: {
    user: () => ({ id: '1', name: 'Alice', email: 'alice@example.com' }),
  },
};

错误处理

GraphQL服务器应该能够处理错误并将其返回给客户端。

const resolvers = {
  Query: {
    user: () => {
      throw new Error('User not found');
    },
  },
};
query {
  user {
    id
    name
    email
  }
}

分页查询

GraphQL可以轻松地实现分页查询。

type Query {
  users(first: Int, after: String): UsersConnection
}

union UsersConnection = UsersPage

type UsersPage {
  edges: [UserEdge]!
  pageInfo: PageInfo!
}

type UserEdge {
  node: User!
  cursor: String!
}

type PageInfo {
  hasNextPage: Boolean!
  endCursor: String
}
const resolvers = {
  Query: {
    users: (parent, { first, after }) => {
      const users = [{ id: '1', name: 'Alice', email: 'alice@example.com' }, { id: '2', name: 'Bob', email: 'bob@example.com' }];
      const pageOfUsers = users.slice(0, first);
      const pageInfo = {
        hasNextPage: pageOfUsers.length < users.length,
        endCursor: pageOfUsers[pageOfUsers.length - 1].id,
      };
      return {
        edges: pageOfUsers.map(user => ({ node: user, cursor: user.id })),
        pageInfo,
      };
    },
  },
};

拆分和组合Schema

在大型应用中,可以将Schema拆分成多个文件,然后组合在一起。

import { makeExecutableSchema } from '@graphql-tools/schema';
import { loadFilesSync } from '@graphql-tools/load-files';
import path from 'path';

const typeDefsArray = loadFilesSync(path.join(__dirname, './schema/**/*.graphql'));
const resolversArray = loadFilesSync(path.join(__dirname, './resolvers/**/*.js'));

const schema = makeExecutableSchema({
  typeDefs: typeDefsArray,
  resolvers: resolversArray,
});

总结

通过本文,你已经学习了如何使用GraphQL来构建现代API。我们介绍了GraphQL的基本概念、安装方法、创建GraphQL服务器、定义Schema、编写Resolver、查询数据、变更数据、使用Apollo Client、GraphQL订阅、数据验证、错误处理、分页查询、拆分和组合Schema等内容。掌握了这些知识,将有助于你在实际工作中更好地利用GraphQL来构建高效、灵活的API。

使用GraphQL可以让你构建出更加高效和灵活的API。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2231357.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

炒到天价的数字头像如何用AI制作——教你用Midjourney轻松打造像素风NFT头像

​ ​ 近年来&#xff0c;NFT数字头像成了热门话题&#xff0c;许多以像素风格为主的头像被炒到天价&#xff0c;像最近比较火的星球兽头像。 它们之所以备受追捧&#xff0c;不仅是因为视觉风格独特&#xff0c;更是因其在NFT领域的稀缺性。 那如果想自己制作一个像素风头像…

网络层2--IP协议

目录 一、虚拟互连网络 二、IP地址 1、IP地址表示方法 2、IP地址分类 3、无分类编址CIDR &#xff08;1&#xff09;网络前缀 &#xff08;2&#xff09;地址块 、 地址掩码 4、IP地址特点 5、地址解析协议ARP &#xff08;1&#xff09;原理 &#xff08;2&#xf…

进程间通信(命名管道 共享内存)

文章目录 命名管道原理命令创建命名管道函数创建命名管道 共享内存原理shmgetFIOK 代码应用&#xff1a;premsnattch 命名管道 用于两个毫无关系的进程间的通信。 原理 Linux文件的路径是多叉树&#xff0c;故文件的路径是唯一的。 让内核缓冲区不用刷新到磁盘中&#xff0c…

基于SSM+小程序的计算机实验室排课与查询管理系统(实验室2)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 1、管理员功能有个人中心&#xff0c;学生管理&#xff0c;教师管理&#xff0c;实验室信息管理&#xff0c;实验室预约管理&#xff0c;取消预约管理&#xff0c;实验课程管理&#xff0…

基于STM32的农业监测与管理系统设计思路介绍(代码示例)

一、项目概述 在全球农业现代化进程中&#xff0c;农业监测与管理系统的研发具有重要意义。本文介绍的基于STM32的农业监测与管理系统&#xff0c;旨在通过智能小车实现对农作物的环境监测、土壤检测等功能。该系统利用手势控制技术&#xff0c;农民可以通过简单的手势指令来操…

分布式架构搭建博客网站

目录 运行环境基础配置需求准备工作配置静态ip修改主机名及host映射开启防火墙时间同步配置免密ssh登录 环境搭建Server-Web端安装LNMP环境软件Server-NFS-DNS端上传博客软件Server-NFS-DNS端设置NFS共享Server-Web设置挂载远程共享目录nginx设置在数据库中创建数据库和用户重启…

基于Transformer的路径规划 - 第五篇 GPT生成策略_解码方法优化

上一篇&#xff1a;基于Transformer的路径规划 - 第四篇 GPT模型优化 在上一篇中&#xff0c;我尝试优化GPT路径生成模型&#xff0c;但没有成功。在随机生成的测试集上&#xff0c;路径规划成功率只有99%左右。而使用传统的路径规划算法&#xff0c;例如A*&#xff0c;路径规划…

【HarmonyOS】鸿蒙应用设置控件通用样式AttributeModifier, @Styles

【HarmonyOS】鸿蒙应用设置控件通用样式AttributeModifier&#xff0c; Styles 前言 在鸿蒙中UI开发经常需要对控件样式进行统一的封装&#xff0c;在API早前版本&#xff0c;一般是通过 Styles进行样式封装复用&#xff1a; Entry Component struct Index {build() {Column(…

[vulnhub]DC:7

https://www.vulnhub.com/entry/dc-7,356/ 端口扫描主机发现 探测存活主机&#xff0c;178是靶机 nmap -sP 192.168.75.0/24 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-03 13:30 CST Nmap scan report for 192.168.75.1 Host is up (0.00037s l…

鸿蒙HarmonyOS应用开发者(基础+高级)认证

文章目录 鸿蒙HarmonyOS应用开发者(基础高级)认证&#x1f449;1.HarmonyOS认证介绍1.1、HarmonyOS发展历程1.2、HarmonyOS NEXT 开发预览版1.3、ArkTS语言开发鸿蒙应用1.4、HarmonyOS应用开发者基础认证的核心内容1.5、HarmonyOS应用开发者高级认证的核心内容1.6、HarmonyOS应…

视频Qoe测量学习笔记(一)

目录 流媒体协议详解 RTSP&#xff1a;实时流式协议 RTCP&#xff1a;实时运输控制协议 RTP&#xff1a;实时运输协议 H.264 流媒体协议详解 RTSP&#xff1a;实时流式协议 由IETF MMusic小组开发&#xff0c;已成为互联网建议标准[RFC 2326]。RTSP本身并不传送数据&…

第三十三章 Vue路由进阶路由模块封装

目录 一、引言 二、完整代码 main.js index.js App.vue Find.vue My.vue 一、引言 在上一个章节中&#xff0c;我们将所有的路由配置都堆在main.js中来实现路径组件的路由&#xff0c;这样做的话非常不利于我们后期对项目的维护。因此正确的做法是将路由模块抽离出来&a…

用插值公式实现滚动进度条动画效果

我们在日常前端开发时在动画的选择上基本都是css&#xff0c;通过css的animation即可满足大部分的开发场景&#xff0c;如果遇到了特殊而比较不容易实现的效果就会考虑到用js来实现&#xff0c;而本次的主题&#xff0c;就是围绕用js来做一个比较不常见的特殊动画效果。 假设我…

【uni-app】创建自定义模板

1. 步骤 打开自定义模板文件夹 在此文件夹下创建模板文件&#xff08;注意后缀名&#xff09; 重新点击“新建页面” 即可看到新建的模板 2. 注意事项 创建的模板必须文件类型对应&#xff08;vue模板就创建*.vue文件, uvue模板就创建*.uvue文件&#xff09;

03哈希表算法/代码随想录

三、哈希表 有效的字母异位词 力扣242 这题是典型的哈希映射&#xff0c;只要将t存到哈希表中&#xff0c;key为t拆解的值&#xff0c;value为t中有过个key这样的值&#xff0c;然后在使用哈希表O&#xff08;1&#xff09;的时间复杂度判断 class Solution {public boolean …

下载安装COPT+如何在jupyter中使用(安装心得,windows,最新7.2版本)

目录 1.到杉树科技官网申请下载COPT 2.安装COPT&配置许可文件 3.在jupyter中使用COPT的python接口 最近看到一本和数学建模有关的新书&#xff1a;《数学建模与数学规划&#xff1a;方法、案例及编程实战》&#xff0c;作为数学建模老手&#xff0c;肯定要学习一下&…

【Linux】——操作系统-进程详解

大家好呀&#xff0c;我是残念&#xff0c;希望在你看完之后&#xff0c;能对你有所帮助&#xff0c;有什么不足请指正&#xff01;共同学习交流哦 本文由&#xff1a;残念ing原创CSDN首发&#xff0c;如需要转载请通知 个人主页&#xff1a;残念ing-CSDN博客&#xff0c;欢迎各…

Excel:vba实现批量插入图片批注

实现的效果&#xff1a;实现的代码如下&#xff1a; Sub InsertImageNamesAndPictures()Dim PicPath As StringDim PicName As StringDim PicFullPath As StringDim RowNum As IntegerDim Name As StringDim Comment As CommentDim folder As FileDialog 定义文件选择对话框 清…

HTML 语法规范——代码注释、缩进与格式、标签与属性、字符编码等

文章目录 一、代码注释1.1 使用注释的主要目的1.2 使用建议二、标签的使用2.1 开始标签和结束标签2.2 自闭合标签2.3 标签的嵌套2.4 标签的有效性三、属性四、缩进与格式4.1 一致的缩进4.2 元素单独占用一行4.3 嵌套元素的缩进4.4 避免冗长的行五、字符编码六、小结在开发 HTML…

闯关leetcode——242. Valid Anagram

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/valid-anagram/ 内容 Given two strings s and t, return true if t is an anagram of s, and false otherwise. Example 1: Input:s “anagram”, t “nagaram” Output:true Example 2: Inp…