日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

大话GraphQL新手上车

發布時間:2023/12/16 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 大话GraphQL新手上车 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

GraphQL是什么?

GraphQL 既是一種用于API的查詢語言也是一個滿足你數據查詢的運行時(來自:官方解釋)

理解起來就是,GraphQL有自己查詢語法,發起的API請求中通過傳遞查詢語句來告訴服務端需要哪些操作和具體數據字段,GraphQL定義了實現規范,各種的語言分別實現了GraphQL功能框架,通過框架可以對查詢語法進行解釋執行,然后返回數據輸出給客戶端


GraphQL的優勢

以下所有查詢和輸出都是來自我的DEMO,DEMO的實現和源碼Github地址下面會提到

語法特性滿足各種需求

  • 支持多操作:query->查詢,mutation->修改,規范是寫在查詢語句前,默認不寫就是query
  • 支持參數,實現各種功能,比如:查詢數據,排序,分頁,... ...等
  • 語法其他特性,別名,片段,定義變量,指令,... ...等
# 查詢語句-有參數 query{student(id:86){idnamesclass{idnumlevelheads}} } # 輸出 {"data": {"student": {"id": 86,"name": "Emma","sclass": {"id": 9,"num": 8,"level": 3,"heads": 68}}} } # 修改 mutation {update(id: 86, name: "66666") {rtmsg} } # 輸出 {"data": {"update": {"rt": 1,"msg": "bingo"}} }

查詢友好性,查詢和輸出關聯

看查詢語句是不是感覺有點兒JSON的味道?查詢語法類JSON格式,前后端都可以很容易上手,查詢語句和輸出數據有緊密的關聯性,通過分析查詢語句就知道輸出的數據內容字段有哪些


靈活性,請求你所要的數據,不多不少

可以自定義查詢語句來獲取需要使用的字段,避免無用字段的輸出,減少不必要數據塊/數據字段查詢邏輯

多字段 # 查詢語句 query{students{idnameclassidsclass{idnumlevelheads}} } # 輸出 {"data": {"students": [{"id": 19,"name": "Savannah","classid":22,"sclass": {"id": 22,"num": 6,"level": 4,"heads": 57}},{"id": 34,"name": "Ariana","classid":33,"sclass": {"id": 33,"num": 3,"level": 4,"heads": 57}}]} } 去掉了不使用的字段輸出,少了字段sclass,就可以不進行sclass數據查詢 # 查詢語句 query{students{idname} } # 輸出 {"data": {"students": [{"id": 19,"name": "Savannah"},{"id": 34,"name": "Ariana"}]} }

API演進,無需劃分版本

API版本迭代無需要進行版本號區分,添加字段不影響現有查詢,請求發起者可以自己定義想要的查詢信息

# Say No http://api.xxx.com/student/v1/ http://api.xxx.com/student/v2/ # ...

自檢性,可查詢輸出所有定義

這個是GraphQL一個很Nice的特性,就是GraphQL服務API可以通過語句查詢出它所支持的類型,開發可以不需要花時間寫API文檔,GraphQL直接幫助開發者快速了解API。

# 查詢語句 {__type(name: "MStudentType") {kindnamefields {namedescriptiontype {name}}} } # 輸出 {"data": {"__type": {"kind": "OBJECT","name": "MStudentType","fields": [{"name": "id","description": "學號","type": {"name": null}},{"name": "name","description": "學生名","type": {"name": null}},{"name": "age","description": "年齡","type": {"name": null}},{"name": "birthdate","description": "生日","type": {"name": null}},{"name": "sclass","description": "班級信息","type": {"name": "MClassType"}}]}} }

基于自檢性,GraphQL開源了輔助工具GraphiQL,方便GraphQL接口調試和自動生成接口文檔

  • GraphQL輔助工具:GraphiQL,可以調試查詢語句,并對接口定義的schema進行文檔可視化展示

    • 查詢語句進行感知
    • 錯誤提示
    • 語句格式化
    • 執行查詢
    • 查看接口定義的schema文檔信息
graphql-dotnet開源項目里的GraphiQL要接入自己開發GraphQL接口,還需要進行簡單的修改調整,后面會說到

.NET下的入門教程

  • 構建ASP.NET MVC5 WebAPI 項目
  • NutGet引入程序包

    • GraphQL
    • GenFu,用于初始化測試數據
  • 基于GraphQL簡單實現一個學生查詢API

    • 支持查詢學生信息列表
    • 支持查詢學生的班級信息
    • 支持查詢學號對應的學生信息
    • 支持修改學生名字

定義【數據類】MStudent.cs(學生類),MClass.cs(班級類),MResult.cs(執行結果類)

public class MStudent {/// <summary>/// 學號/// </summary>public int Id { get; set; }/// <summary>/// 名字/// </summary>public string Name { get; set; }/// <summary>/// 年齡/// </summary>public int Age { get; set; }/// <summary>/// 所在班級編號/// </summary>public int ClassId { get; set; }/// <summary>/// 生日/// </summary>public DateTime Birthdate { get; set; }/// <summary>/// 班級/// </summary>public MClass SClass { get; set; } }public class MClass {public int Id { get; set; }/// <summary>/// 年級/// </summary>public int Level { get; set; }/// <summary>/// 第幾班/// </summary>public int Num { get; set; }/// <summary>/// 總人數/// </summary>public int Heads { get; set; } }public class MResult {/// <summary>/// 輸出結果,0=失敗,1=成功/// </summary>public int rt { get; set; }/// <summary>/// 說明信息/// </summary>public string msg { get; set; } }

定義GraphType類 MStudentType,MClassType,MResultType 繼承ObjectGraphType<TSourceType> ,TSourceType泛型對應到【數據類】
構造函數里通過Field去添加可以被查詢的數據字段,包括:描述以及字段內容獲取的處理方法,等

public class MStudentType : ObjectGraphType<MStudent> {private static BStudent _bll { get; set; }public MStudentType() {if (_bll == null) _bll = new BStudent();Field(d => d.Id).Description("學號");Field(d => d.Name).Description("學生名");Field(d => d.Age).Description("年齡");Field(d => d.Birthdate).Description("生日");Field<MClassType>("sclass", resolve: d => {//緩存中已經存在就直接返回if (d.Source.SClass != null) return d.Source.SClass;//從DB/緩存中獲取數據var classId = d.Source?.ClassId ?? 0;if (classId > 0) d.Source.SClass = _bll.GetClass(d.Source.ClassId);return d.Source.SClass;},description:"班級信息");} }public class MClassType : ObjectGraphType<MClass> {public MClassType() {Field(d => d.Level).Description("年級");Field(d => d.Heads).Description("人數");Field(d => d.Id).Description("編號");Field(d => d.Num).Description("班級");} }public class MResultType : ObjectGraphType<MResult> {public MResultType() {Field(d => d.rt);Field(d => d.msg);} }

定義Schema的操作類(query/mutation),繼承 ObjectGraphType,有:StudentQuery,StudentMutation

public class StudentQuery : ObjectGraphType {public StudentQuery(BStudent bll) {//查詢-有參數idField<MStudentType>("student", arguments: new QueryArguments(new QueryArgument<IntGraphType>() {Name = "id"}), resolve: d => {var id = d.Arguments["id"].GetInt(0, false);return bll.GetModel(id); ;});//查詢-列表Field<ListGraphType<MStudentType>>("students", resolve: d => {return bll.GetStudents();});}} }public class StudentMutation : ObjectGraphType {public StudentMutation(BStudent bll) {Field<MResultType>("update", arguments: new QueryArguments(new QueryArgument<IntGraphType> {Name = "id"},new QueryArgument<StringGraphType> {Name = "name"}), resolve: (d) => {var id = d.Arguments["id"].GetInt(0, false);var name = d.Arguments["name"].GetString("");if (id <= 0) return new MResult {rt = 0,msg = "非法學號"};if (name.IsNullOrWhiteSpace()) return new MResult {rt = 0,msg = "非法名字"};var isSc = bll.UpdateName(id, name);if (!isSc) return new MResult {rt = 0,msg = "更新失敗"};return new MResult {rt = 1,msg = "bingo"};});} }

在控制器里添加接口,構造Schema對象,根據查詢條件解析執行返回結果輸出
Query = StudentQuery,Mutation = StudentMutation

/// <summary> /// graphql demo 接口 /// </summary> /// <returns></returns> [HttpPost] [Route("query")] public object Test_Query() {var r = HttpContext.Current.Request;var query = r.GetF("query");var bll = new BStudent();var schema = new Schema { Query = new StudentQuery(bll), Mutation = new StudentMutation(bll) };var result = new DocumentExecuter().ExecuteAsync(options => {options.Schema = schema;options.Query = query;}).GetAwaiter();var json = new DocumentWriter(indent: true).Write(result);return result.GetResult(); }

GraphiQL工具的接入

  • Git Clone graphql-dotnet
  • 安裝NodeJS環境
  • 命令工具CMD打開graphql-dotnet/src/GraphQL.GraphiQL/ 執行下面命令

    • npm install -g yarn
    • yarn install
    • yarn start
  • 運行graphql-dotnet/src/GraphQL.GraphiQL 就可以啟動:http://localhost:47080/
  • 根據自己的情況調整:graphql-dotnet/src/GraphQL.GraphiQL/app/app.js 腳本,如下面貼出的代碼

    • url=graphql接口地址
    • 如果需要投入生產使用,可以把接口地址進行url傳入,或者支持輸入框輸入地址,不固定接口地址
  • 每次調整完需要重新執行 yarn start,前端會使用webpack進行打包操作,執行完成后刷新頁面即可
//調整如下 import React from 'react'; import ReactDOM from 'react-dom'; import GraphiQL from 'graphiql'; import axios from 'axios'; import 'graphiql/graphiql.css'; import './app.css';function graphQLFetcher(graphQLParams) {console.log(graphQLParams["query"]);return axios({method: 'post',url: "http://127.0.0.1:5656/query",//window.location.origin + '/api/graphql',data: "query=" + graphQLParams["query"],headers: { 'Content-Type': 'application/x-www-form-urlencoded' }}).then(resp => resp.data); } ReactDOM.render(<GraphiQL fetcher={graphQLFetcher} />, document.getElementById('app'));

總結

  • 對于應用我覺得可以嘗試使用到新項目需求中,或者現有合適應用場景進行重構,等服務運行穩定,并且開發上手后即可進行大范圍的使用
  • 對于RestFul和GraphQL的比較,我覺得沒有最好的協議,只有最合適的場景

資源

  • Demo源碼:

    • Demo代碼到我的Gtihub項目(GraphQLDemo)
  • 學習資料

    • 知乎-什么是GraphQL
    • GraphQL語法入門
    • GraphQL中文官網
    • How To GraphQL
    • GraphQL 搭配 Koa 最佳入門實踐

原文首發于博客

總結

以上是生活随笔為你收集整理的大话GraphQL新手上车的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。