关于graphql快速入门

简介: 关于graphql快速入门

GraphQL是什么?

一种用于 API 的查询语言,GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。

GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。

GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

关于SQL

SQL 指结构化查询语言,全称是 Structured Query Language。

在您的网站中使用 SQL,比如要创建一个显示数据库中数据的网站,您需要:

1、RDBMS 数据库程序(比如 MS Access、SQL Server、MySQL)
2、使用服务器端脚本语言,(比如 PHP 、 ASP、Node)
3、使用 SQL 来获取您想要的数据
4、使用 HTML / CSS

如何使用

GraphQL 是一种描述客户端如何向服务端请求数据的API语法,类似于 RESTful API 规范。

客户端可以通过 HTTP GET 发送请求,请求的结构如下所示:

http://myapi/graphql?query={me{name}}

然后你的 GraphQL HTTP 服务器应当能够处理 HTTP GET 方法。

// server.js
const express = require('express')
const { graphqlHTTP } = require('express-graphql')
const schema = require('./schema')
const cors = require('cors')

const app = express()
app.use(cors({
  origin: 'http://localhost:3000',
  methods: 'GET,POST,OPTIONS,DELETE,PUT'
}))
app.use('/graphql', graphqlHTTP({
  schema,
  graphiql: true
}))
app.listen(4000, () => {
  console.log('服务器启动:http://localhost:4000')
})

express-graphql 的 npm 包是用来创建一个 GraphQL HTTP 服务。用它结合常规 Express 来运行 GraphQL,作用是处理请求然后返回数据。

graphql 的 npm 包是 GraphQL 规范的语法实现,用于在 Node.js 环境中运行。GraphQL API 基于类型和字段的方式进行组织。所以这个包的作用定义类型和字段提供 API 方法。

// schema.js
const graphql = require('graphql')
const { GraphQLObjectType, GraphQLString, GraphQLSchema, GraphQLList, GraphQLNonNull } = graphql

const User = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
    id: { type: GraphQLString },
    name: { type: GraphQLString }
  })
})

const UserInfo = { id: "1", name: "张三" }

const RootQuery = new GraphQLObjectType({
  name: 'RootQuery',
  fields: {
    me: {
      type: User,
      args: {
        // 参数
      },
      resolve (parent, args) {
        return UserInfo
      }
    }
  }
})

module.exports = new GraphQLSchema({
  query: RootQuery
})

然后启动服务,当我们访问 http://localhost:4000/graphql?query={me{name}} 页面会查询出下面结果:

{
  "data": {
    "me": {
      "name": "张三"
    }
  }
}

GraphQL 主要是作用于数据接口,比如前端后端交互。客户端自由筛选去获取服务端事先定义好的数据,提高了交互接口的灵活性。比如上述接口,只有 name 字段,现在我又想访问 id 字段,只需要在接口请求的时候带上你要获取那些字段就可以。

http://localhost:4000/graphql?query={me{name,id}}

向你的 API 发出一个 GraphQL 请求就能准确获得你想要的数据,不多不少。 GraphQL 查询总是返回可预测的结果。使用 GraphQL 的应用可以工作得又快又稳,因为控制数据的是我们的应用,而不是服务器。

GraphQL 查询不仅能够获得资源的属性,还能沿着资源间引用进一步查询。典型的 REST API 请求多个资源时得载入多个 URL,而 GraphQL 可以通过一次请求就获取你应用所需的所有数据。这样一来,即使是比较慢的移动网络连接下,使用 GraphQL 的应用也能表现得足够迅速。

const graphql = require('graphql')
const { GraphQLObjectType, GraphQLString, GraphQLSchema, GraphQLList, GraphQLNonNull } = graphql

const categories = [
  { id: '1', name: '图书' },
  { id: '2', name: '手机' },
  { id: '3', name: '面包' },
  { id: '4', name: '电脑' },
]

// products.category 对应的是 categories.id 表示分类id
const products = [
  { id: '1', name: '深入浅出nodeJS', category: '1' },
  { id: '2', name: '高级程序设计', category: '1' },
  { id: '3', name: '华为手机', category: '2' },
  { id: '2', name: 'mac电脑', category: '4' },
]

const Category = new GraphQLObjectType({
  name: 'Category',
  fields: () => ({
    id: { type: GraphQLString },
    name: { type: GraphQLString },
    products: {
      type: new GraphQLList(Product),
      resolve (parent) {
        // parent是当前分类,根据分类找到对应的产品列表
        return products.filter(item => item.category === parent.id)
      }
    }
  })
})

const Product = new GraphQLObjectType({
  name: 'Product',
  fields: () => ({
    id: { type: GraphQLString },
    name: { type: GraphQLString },
    category: {
      type: Category,
      resolve (parent) {
        // category: '1' 根据分类的id找到分类对应的对象
        return categories.find(item => item.id === parent.category)
      }
    }
  })
})


// 定义根类型
const RootQuery = new GraphQLObjectType({
  name: 'RootQuery',
  fields: {
    // 根据ID查询分类
    getCategory: {
      type: Category,
      args: {
        id: { type: GraphQLString },
      },
      resolve (parent, args) {
        return categories.find((item) => item.id === args.id)
      }
    },
    // 查询所有分类
    getCategoryList: {
      type: new GraphQLList(Category),
      args: {
      },
      resolve (parent, args) {
        return categories
      }
    },
    // 根据ID查询产品
    getProduct: {
      type: Product,
      args: {
        id: { type: GraphQLString },
      },
      resolve (parent, args) {
        return products.find((item) => item.id === args.id)
      }
    },
    // 查询所有产品
    getProductList: {
      type: new GraphQLList(Product),
      args: {
      },
      resolve (parent, args) {
        return products
      }
    }
  }
})

module.exports = new GraphQLSchema({
  query: RootQuery
})

一个分类下面是有多个产品,这种一对多的关系。当我们查询分类的时候,还能查出具体分类里面的产品列表,这种关联关系就是沿着资源间引用进一步查询的特点。

相关文章
|
API 开发者
GraphQL全面深度讲解
GraphQL是一种查询语言和运行引擎,允许开发者在一个请求中自定义并获取所有所需数据,提供准确且无冗余的数据返回,但可能需要开发者学习新的语言并投入更多时间来维护数据模型。
700 5
GraphQL全面深度讲解
|
10月前
|
前端开发 JavaScript Java
Java打包jar运行时分离lib和jar
在`pom.xml`的`build`节点中,设置`packaging`为`jar`,并配置插件分离依赖库到`lib`目录和资源文件到`resources`目录。这样可以在运行时通过`-Dloader.path=lib,resources`加载外部依赖和资源文件,便于独立升级依赖库和修改资源文件,而无需重新打包程序。具体插件包括`maven-dependency-plugin`、`maven-resources-plugin`和`spring-boot-maven-plugin`等。
581 1
|
Java
【Java基础】输入输出流(IO流)
Java基础、输入输出流、IO流、流的概念、输入输出流的类层次结构图、使用 InputStream 和 OutputStream流类、使用 Reader 和 Writer 流类
451 2
|
API 缓存 人工智能
深入调查研究GraphQL
【11月更文挑战第19天】
254 5
|
运维 监控 测试技术
如何确保微服务架构的高可用性?
如何确保微服务架构的高可用性?
485 57
|
缓存 前端开发 测试技术
使用GraphQL进行高效数据查询的技术指南
【5月更文挑战第24天】GraphQL是Facebook开源的查询语言,用于高效数据查询,解决RESTful API的过度获取、不足获取及冗余问题。它允许客户端指定所需数据,实现按需获取,具有客户端定义查询、灵活性和可扩展性、减少API数量等优势。GraphQL基于类型和模式工作,通过定义模式、实现解析器、整合前后端及测试优化来实现查询。适用于灵活数据需求、复杂关联查询和实时数据更新的场景,但也存在学习成本高、服务器实现复杂和性能优化问题。
|
JavaScript 安全 前端开发
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
这篇文章介绍了Vue项目中解决跨域问题的方法,包括使用CORS设置HTTP头、通过Proxy代理服务器进行请求转发,以及在vue.config.js中配置代理对象的策略。
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
|
存储 Java PHP
【JVM】垃圾回收机制(GC)之引用计数和可达性分析
【JVM】垃圾回收机制(GC)之引用计数和可达性分析
232 0
|
Ubuntu 关系型数据库 MySQL
Ubuntu系统本地搭建WordPress网站并发布公网实现远程访问
Ubuntu系统本地搭建WordPress网站并发布公网实现远程访问
|
存储 缓存 监控
深入理解Java线程池ThreadPoolExcutor实现原理、数据结构和算法(源码解析)
Java线程池的核心组件包括核心线程数、最大线程数、队列容量、拒绝策略等。核心线程数是线程池长期维持的线程数量,即使这些线程处于空闲状态也不会被销毁;最大线程数则是线程池允许的最大线程数量,当任务队列已满且当前线程数未达到最大线程数时,线程池会创建新线程执行任务;队列容量决定了任务队列的最大长度,当新任务到来时,如果当前线程数已达到核心线程数且队列未满,任务将被放入队列等待执行;拒绝策略则定义了当线程池无法处理新任务时的行为,如抛出异常、丢弃任务等。
363 1