小白可以看懂的「GraphQL」,GraphQL到底是啥样

news2024/11/27 8:36:58

GraphQL是一种用于API的查询语言,可以在服务端定义GraphQL Schema,客户端可以向服务端发送GraphQL请求,服务端执行GraphQL查询,并将结果作为JSON返回给客户端。

下面是一个使用golang实现GraphQL的示例,首先需要安装golang的GraphQL库github.com/graphql-go/graphql

第一步定义GraphQL Schema

package main

import "github.com/graphql-go/graphql"

// 定义User结构体
type User struct {
    ID   int
    Name string
    Age  int
}

// 定义GraphQL Schema
var Schema, _ = graphql.NewSchema(graphql.SchemaConfig{
    Query: graphql.NewObject(graphql.ObjectConfig{
        Name: "Query",
        Fields: graphql.Fields{
            // 定义getUser查询,查询一个用户的信息
            "getUser": &graphql.Field{
                Type: UserObject,
                Args: graphql.FieldConfigArgument{
                    "id": &graphql.ArgumentConfig{
                        Type: graphql.Int,
                    },
                },
                Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                    // 处理getUser查询的逻辑
                    userID, ok := p.Args["id"].(int)
                    if !ok {
                        return nil, nil
                    }
                    var user = User{
                        ID:   userID,
                        Name: "Tom",
                        Age:  18,
                    }
                    return user, nil
                },
            },
        },
    }),
})

// 定义User类型
var UserObject = graphql.NewObject(graphql.ObjectConfig{
    Name: "User",
    Fields: graphql.Fields{
        "id": &graphql.Field{
            Type: graphql.Int,
        },
        "name": &graphql.Field{
            Type: graphql.String,
        },
        "age": &graphql.Field{
            Type: graphql.Int,
        },
    },
})

以上代码中,定义了一个叫做User的类型,以及一个叫做getUser的查询,getUser查询需要一个名为id的参数,返回一个User类型的对象。

② 执行GraphQL查询

package main

import (
    "encoding/json"
    "fmt"
    "net/http"

    "github.com/graphql-go/graphql"
    "github.com/graphql-go/handler"
)

func main() {
    // 定义http请求处理函数
    http.Handle("/graphql", handler.New(&handler.Config{
        Schema: &Schema,
        Pretty: true,
    }))

    // 启动http服务
    fmt.Println("Server running on port 8080")
    http.ListenAndServe(":8080", nil)
}

以上代码中,使用github.com/graphql-go/handler库创建一个http处理器,并监听8080端口。

接下来,可以使用HTTP Client来测试GraphQL查询:

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

func main() {
    // 定义GraphQL查询
    query := `
        query getUser($id:Int!) {
            user:getUser(id:$id) {
                id
                name
                age
            }
        }
    `

    // 定义查询参数
    params := struct {
        Query     string      `json:"query"`
        Variables interface{} `json:"variables"`
    }{
        Query: query,
        Variables: map[string]interface{}{
            "id": 1,
        },
    }

    // 将查询参数编码为JSON格式
    requestBody, _ := json.Marshal(params)

    // 发送GraphQL查询请求
    resp, _ := http.Post("http://localhost:8080/graphql", "application/json", bytes.NewBuffer(requestBody))

    // 读取查询结果
    var result struct {
        Data   interface{} `json:"data"`
        Errors []struct {
            Message string `json:"message"`
        } `json:"errors"`
    }
    json.NewDecoder(resp.Body).Decode(&result)

    // 处理查询结果
    if len(result.Errors) > 0 {
        fmt.Println(result.Errors[0].Message)
    } else {
        fmt.Printf("%+v\n", result.Data)
    }
}

以上代码中,定义了一个叫做getUser的查询,并且将查询变量id的值设置为1。将查询参数编码为JSON格式,并通过HTTP Post发送GraphQL查询请求。最后,处理查询结果并打印到控制台。

总结:graphQL给我们带来的diff是什么?

可以给GraphQL形象地比喻成一名个人管家或者服务员。客户端向服务端发送一个需要的数据需求(就像是顾客点菜),服务端的个人管家/服务员(即GraphQL)收到需求后,帮你去找到所有数据,然后将所有数据优化打包成一个请求结果返回给客户端(即将所有的菜打包成一份菜单,客户端只需要按需取数据即可)。

下面是GraphQL的一些优点和缺点:

优点:

  • 精细的数据获取:GraphQL可以精确获取客户端需要的数据,减少数据传输量和网络请求次数,提高性能。
  • 灵活的数据查询:GraphQL查询语言非常灵活,支持多种查询方式,可以方便的定制查询条件,满足客户端的不同数据需求。
  • 自描述性:GraphQL服务端会提供一份Schema,客户端可以根据该Schema自动生成文档或者代码,方便开发和协作。
  • 适用于多平台:GraphQL不依赖具体的数据库和平台,适用于多种语言和开发框架。

缺点:

  • 学习成本:相对于RESTful API,GraphQL需要更多的学习成本,包括查询语言和Schema定义等。
  • 需要服务端支持:GraphQL需要服务端实现支持,需要服务端和客户端都做相应的改造,不能直接覆盖已有的API。
  • 安全问题:由于GraphQL可以让客户端获取更小粒度的数据,因此很容易暴露一些敏感数据给客户端,需要在服务端实现中特别注意安全问题。

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

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

相关文章

Ajax请求与浏览器缓存

在现代Web应用程序中,前端代码充斥着大量的Ajax请求,如果对于Ajax请求可以使用浏览器缓存,那么可以显著地减少网络请求,提高程序响应速度。 1. Ajax Request 使用jQuery框架可以很方便的进行Ajax请求,示例代码如下&a…

RISC-V 学习篇之特权架构下的中断异常处理

RISC-V 学习篇之特权架构下的中断异常处理 控制流和Trap特权架构简单的嵌入式系统的机器模式机器模式下的异常处理mtvec(Machine Trap-Vector Base-Address)mepc(Machine Exception Program Counter)mcause(Machine Cause&#xf…

Erlang/OTP 26 正式发布

导读Erlang 是一种通用的并发函数式程序设计语言。Erlang 也可以指 Erlang/OTP 的通称,开源电信平台 (OTP) 是 Erlang 的常用执行环境及一系列标准组件。 Erlang/OTP 26.0 已正式发布。这是一个重要版本更新,包含许多新特性、改进和不兼容的变化。 主要…

C++11右值

C11右值 类型与值类别左值纯右值将亡值内置类型类类型 左值引用和右值引用内置类型右值引用:具有右值引用自身为左值。右值引用与函数重载函数返回值 自定义类型右值引用构造函数的隐式转换右值引用与函数重载类类型作为函数的返回值 右值引用与函数模板泛化版本&am…

Java005——idea编写和运行第一个Java程序HelloWorld

1、首相需要了解什么是IDE(集成开发环境)? 2、了解Java有哪些主流的开发工具? 一、创建一个文件夹用来存放Java项目 二、创建一个空项目 点击idea首页新建项目按钮 创建一个空项目 这样空项目就创建好了 三、在空项目中新建一…

leetcode 数据库题 584,585,586,595,596,601,602,607,608,610

leetcode 数据库题 第三弹 584. 寻找用户推荐人585. 2016年的投资586. 订单最多的客户595. 大的国家596. 超过5名学生的课601. 体育馆的人流量602. 好友申请 II :谁有最多的好友607. 销售员608. 树节点610. 判断三角形小结 584. 寻找用户推荐人 https://leetcode.cn…

<数据结构>NO7.二叉树(附Oj练习题)

👇二叉树的完整代码在👇 syseptember的gitee仓库:二叉树https://gitee.com/syseptember/data-structure/tree/1513789167062c75dc172366199ce7a6b0577cc7/BinaryTree2/BinaryTree2 目录 树的概念及结构 0x01.树的概念 0x02.树的相关概念 …

快速定位接口问题,JMeter方法论,跨线程组接口关联测试!

目录 【前言】 【步骤】 1. 准备工作 2. 创建线程组 3. 创建HTTP请求 4. 添加正则表达式提取器 5. 添加HTTP请求关联控制器 6. 设置断言和验证器 7. 运行测试 【代码】 【结论】 【前言】 在进行接口测试时,接口之间的关联经常是我们需要重点测试的点之…

如何手写网络协议栈

哈喽,我是子牙,一个很卷的硬核男人。喜欢研究底层,聚焦做那些大家想学没地方学的课程:手写操作系统、手写虚拟机、手写编程语言…目前做了两门课:手写OS、手写JVM 今天想跟大家聊一个黑科技:手写网络协议栈…

Python的编码规范

目录 1、每个 import 语句只导入一个模块,尽量避免一次导入多个模块, 2、不要在行尾添加分号,也不要用分号将两条命令放在同一行, 3、建议每行不超过 80 个字符, 4、使用必要的空行可以增加代码的可读性 5、通常情…

让百万大学生崩溃的在线OJ,如何破局?

目录 一、在线OJ的的原理 二、在线OJ的使用规则 三、注意事项 1.关于作弊 2.如何防止作弊 3.输入输出格式 4.换行问题 四、经典在线OJ坑人题目以及博主被坑经历 五、提交不成功及解决方法 六、如何得心应手的拿下OJ系统 七、在线OJ的骗分技巧 在线OJ(Onl…

OpenGL简介

1.简介 一般它被认为是一个API,包含了一系列可以操作图形、图像的函数。然而,OpenGL本身并不是一个API,它仅仅是一个由Khronos组织制定并维护的规范(Specification)。OpenGL规范严格规定了每个函数该如何执行,以及它们的输出值。…

为何要用分布式锁Redis实现分布式锁

为何要用分布式锁 一、为什么要使用分布式锁 为了保证一个方法在高并发情况下的同一时间只能被同一个线程执行,在传统单体应用单机部署的情况下,可以使用Java并发处理相关的API(如ReentrantLcok或synchronized)进行互斥控制。但是,随着业务…

《论文阅读》连续前缀提示Prompt:table-to-text和摘要生成 ACL2021

《论文阅读》连续前缀提示Prompt:table-to-text和摘要生成 ACL2021 前言相关知识Table-to-Text Generation自编码语言模型自回归语言模型简介任务定义部分参数更新代码实验结果前言 你是否也对于理解论文存在困惑? 你是否也像我之前搜索论文解读,得到只是中文翻译的解读后…

高级算法工程师的工作职责(合集)

高级算法工程师的工作职责1 职责: 1、调研跟踪智能穿戴产品相关算法,为公司产品决策提供参考; 2、设计开发智能穿戴产品的计步、睡眠、心率、血氧饱和度、血压、心率变异性等相关参数的提取算法; 3、撰写算法开发文档,包括算法流程、测试方案…

小黑西安归来,政审完毕,眼睛手术做完一直在家躺着第5天的leetcode之旅:852. 山脉数组的峰顶索引

小黑代码 class Solution:def peakIndexInMountainArray(self, arr: List[int]) -> int:# 数组长度n len(arr)# 寻求山峰for i in range(n-1):if arr[i1] < arr[i]:return ireturn -1小黑二分模版 class Solution:def peakIndexInMountainArray(self, arr: List[int])…

Linux——内存和DMA

目录 本章目标&#xff1a; 一、内存组织 二、按页分配内存 三、slab分配器 四、不连续内存页分配 五、per-CPU变量 本章目标&#xff1a; 在前面的所有例子中&#xff0c;我们使用的都是全局变量或在栈上分配的内存。本章我们将先讨论如何动态分配内存和per-CPU变量。类…

实战-k8s中部署tomcat(四)

先下载资源&#xff1a;k8s中安装Tomcat 测试 k8s 集群中部署 tomcat 服务 #把 tomcat.tar.gz 上传到 k8s-node1&#xff0c;手动解压 [rootk8s-node1 ~]# ctr images import tomcat.tar.gz [rootk8s-master ~]# kubectl apply -f tomcat.yaml apiVersion: v1 #pod属于k8…

Augmentation Matters:一种简单而有效的半监督语义分割方法(CVPR2023)

文章目录 Augmentation Matters: A Simple-yet-Effective Approach to Semi-supervised Semantic Segmentation摘要本文方法Random Intensity-based AugmentationsAdaptive Label-aided CutMix 实验结果 Augmentation Matters: A Simple-yet-Effective Approach to Semi-superv…

迅为RK3568开发板2800页手册+220集视频

iTOP-3568开发板采用瑞芯微RK3568处理器&#xff0c;内部集成了四核64位Cortex-A55处理器。主频高达2.0Ghz&#xff0c;RK809动态调频。集成了双核心架构GPU&#xff0c;ARM G52 2EE、支持OpenGLES1.1/2.0/3.2OpenCL2.0、Vulkan 1.1、内高性能2D加速硬件。 内置NPU 内置独立NP…