當(dāng)下最流行的API查詢語言GraphQL-再不用你就out了

一種用于 API 的查詢語言

GraphQL 既是一種用于 API 的查詢語言也是一個(gè)滿足你數(shù)據(jù)查詢的運(yùn)行時(shí)亮蒋。 GraphQL 對(duì)你的 API 中的數(shù)據(jù)提供了一套易于理解的完整描述乘粒,使得客戶端能夠準(zhǔn)確地獲得它需要的數(shù)據(jù)翻诉,而且沒有任何冗余匀借,也讓 API 更容易地隨著時(shí)間推移而演進(jìn),還能用于構(gòu)建強(qiáng)大的開發(fā)者工具偎漫。

根據(jù)請(qǐng)求得到你想要的數(shù)據(jù)

最重要的是得到不多不少溅固、正正好的數(shù)據(jù)。

向你的 API 發(fā)出一個(gè) GraphQL 請(qǐng)求就能準(zhǔn)確獲得你想要的數(shù)據(jù)晾剖,不多不少锉矢。 GraphQL 查詢總是返回可預(yù)測的結(jié)果。使用 GraphQL 的應(yīng)用可以工作得又快又穩(wěn)齿尽,因?yàn)榭刂茢?shù)據(jù)的是應(yīng)用沈撞,而不是服務(wù)器。

這篇博客我們就主要就講講根據(jù)請(qǐng)求獲取不多不少的數(shù)據(jù)雕什,這也是GraphQL最大的優(yōu)點(diǎn)之一缠俺。

GraphQL來源

GraphQL是由Facebook開源的;

具體實(shí)現(xiàn)

由于最近在弄一個(gè)開源項(xiàng)目Email-Dashboard,
里面也會(huì)用到GraphQL來實(shí)現(xiàn)API查詢贷岸,這里實(shí)現(xiàn)語言就采用golang壹士,該項(xiàng)目里面就用的是golang。

golang GraphQL官方庫
GraphQL結(jié)合http實(shí)現(xiàn)Handler

main.go具體實(shí)現(xiàn):

import (
    "fmt"
    "net/http"

    "github.com/gin-gonic/gin"
    "github.com/graphql-go/graphql"
    "github.com/graphql-go/handler"
    gqlhandler "github.com/graphql-go/handler"
)

type Comment struct {
    ID     int    `json:"id"`
    Author string `json:"author"`
    Body   string `json:"body"`
    PostID int    `json:"postId"`
}

func main() {
    runGin()
}

//使用http實(shí)現(xiàn)GraphQL
func runHTTP() {
    rootQuery := graphql.ObjectConfig{
        Name: "Query",
        Fields: graphql.Fields{
            "comment": &graphql.Field{
                Type: CreateType(),
                Args: graphql.FieldConfigArgument{
                    "id": &graphql.ArgumentConfig{
                        Type: graphql.NewNonNull(graphql.Int),
                    },
                },
                Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                    id := p.Args["id"]
                    v, _ := id.(int)
                    return &Comment{ID: v, Author: "aa", Body: "bb", PostID: 2}, nil
                },
            },
        }}

    schema, err := graphql.NewSchema(graphql.SchemaConfig{
        Query: graphql.NewObject(rootQuery),
    })
    if err != nil {
        panic(err)
    }
    graphqlHandler := gqlhandler.New(&gqlhandler.Config{
        Schema: &schema,
    })
    graphiqlHandler := gqlhandler.New(&gqlhandler.Config{
        Schema:     &schema,
        Pretty:     true,
        GraphiQL:   false,
        Playground: true,
    })

    http.Handle("/graphql", graphqlHandler)
    http.Handle("/graphiql", graphiqlHandler)
    fmt.Println(http.ListenAndServe(":8080", nil))
}

//使用gin實(shí)現(xiàn)GraphQL
func runGin() {
    router := gin.Default()
    router.GET("/", func(c *gin.Context) {
        c.String(http.StatusOK, fmt.Sprintf("Hello from GraphQL API!"))
    })

    api := router.Group("/api/v3")

    //核心入口
    rootQuery := graphql.ObjectConfig{
        Name: "Query",
        Fields: graphql.Fields{
            //要請(qǐng)求的元素
            "comment": &graphql.Field{
                //該元素里面的元素類型聲明
                Type: CreateType(),
                //query參數(shù)聲明
                Args: graphql.FieldConfigArgument{
                    "id": &graphql.ArgumentConfig{
                        Type: graphql.NewNonNull(graphql.Int),
                    },
                },
                Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                    //具體參數(shù)獲取
                    id := p.Args["id"]
                    v, _ := id.(int)
                    //數(shù)據(jù)返回
                    return &Comment{ID: v, Author: "aa", Body: "bb", PostID: 2}, nil
                },
            },
        }}

    schema, err := graphql.NewSchema(graphql.SchemaConfig{
        Query: graphql.NewObject(rootQuery),
    })
    if err != nil {
        panic(err)
    }

    api.POST("/graphql", GraphqlHandler(schema))
    api.GET("/graphql", GraphqlHandler(schema))

    router.Run(":8080")
}

func CreateType() *graphql.Object {
    return graphql.NewObject(graphql.ObjectConfig{
        Name: "Comment",
        Fields: graphql.Fields{
            "id": &graphql.Field{
                Type: graphql.NewNonNull(graphql.Int),
            },
            "author": &graphql.Field{
                Type: graphql.String,
            },
            "body": &graphql.Field{
                Type: graphql.String,
            },
            "postId": &graphql.Field{
                Type: graphql.NewNonNull(graphql.Int),
            },
        },
    })
}

//為GraphQL handler 結(jié)合gin封裝的func
func GraphqlHandler(schema graphql.Schema) gin.HandlerFunc {
    h := handler.New(&handler.Config{
        Schema: &schema,
    })

    return func(c *gin.Context) {
        h.ServeHTTP(c.Writer, c.Request)
    }
}

go run main.go運(yùn)行上面的實(shí)例偿警,即可發(fā)布GraphQL接口

結(jié)果展示

gin通過http://localhost:8080/api/v3/graphql訪問躏救;
http通過http://localhost:8080/graphql訪問;
如圖片中帶上具體的query參數(shù)即可螟蒸;

graphql.png

如上圖片中盒使,如果你只需要id和author,則你的query參數(shù)就設(shè)置成{comment(id:1){id,author}}七嫌;
這樣就只會(huì)給你返回id和author的json串少办。
這樣也就是返回不多不少,剛剛好的數(shù)據(jù)诵原。

后續(xù)

第一篇GraphQL的入門介紹就到這了英妓;
GraphQL的介紹也會(huì)持續(xù)更新,有問題可以在下面留言绍赛。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蔓纠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子吗蚌,更是在濱河造成了極大的恐慌腿倚,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚯妇,死亡現(xiàn)場離奇詭異敷燎,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)侮措,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門懈叹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人分扎,你說我怎么就攤上這事澄成。” “怎么了畏吓?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵墨状,是天一觀的道長。 經(jīng)常有香客問我菲饼,道長肾砂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任宏悦,我火速辦了婚禮镐确,結(jié)果婚禮上包吝,老公的妹妹穿的比我還像新娘。我一直安慰自己源葫,他們只是感情好诗越,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著息堂,像睡著了一般嚷狞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上荣堰,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天床未,我揣著相機(jī)與錄音,去河邊找鬼振坚。 笑死薇搁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的屡拨。 我是一名探鬼主播只酥,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼呀狼!你這毒婦竟也來了裂允?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤哥艇,失蹤者是張志新(化名)和其女友劉穎绝编,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體貌踏,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡十饥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了祖乳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逗堵。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖眷昆,靈堂內(nèi)的尸體忽然破棺而出蜒秤,到底是詐尸還是另有隱情,我是刑警寧澤亚斋,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布作媚,位于F島的核電站,受9級(jí)特大地震影響帅刊,放射性物質(zhì)發(fā)生泄漏纸泡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一赖瞒、第九天 我趴在偏房一處隱蔽的房頂上張望女揭。 院中可真熱鬧蚤假,春花似錦、人聲如沸田绑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掩驱。三九已至,卻和暖如春冬竟,著一層夾襖步出監(jiān)牢的瞬間欧穴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工泵殴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涮帘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓笑诅,卻偏偏與公主長得像调缨,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吆你,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容