昨天完成了hello world,今天接着做getAll和getOne,主要是學習傳參和參數處理.
建立models目錄,增加article.go檔案,内容如下:
package models
import "errors"
type Article struct {
ID int `json:"id"`
Title string `json:"title"`
Content string `json:"content"`
}
// For this demo, we're storing the article list in memory
var articleList = []Article{
Article{ID: 1, Title: "Article 1,文章1", Content: "Article 1 body,中國加油"},
Article{ID: 2, Title: "Article 2,文章2", Content: "Article 2 body,武漢加油"},
}
// Return a list of all the articles
func GetAllArticles() []Article {
return articleList
}
// Get article
func GetArticleByID(id int) (*Article, error) {
for _, a := range articleList {
if a.ID == id {
return &a, nil
}
}
return nil, errors.New("Article not found")
}
很簡單,定義了Article結構體,然後初始化了一個slice,裡面有兩篇文章.定義了兩個函數,一個是傳回全部的文章,一個是根據id查找單篇文章.
接下來,建立schema目錄,增加article.go檔案:
package schema
import (
"errors"
"graphqldemo/models"
"github.com/graphql-go/graphql"
)
// 定義查詢對象的字段,支援嵌套
var articleType = graphql.NewObject(graphql.ObjectConfig{
Name: "Article",
Description: "Article Model",
Fields: graphql.Fields{
"id": &graphql.Field{
Type: graphql.Int,
},
"title": &graphql.Field{
Type: graphql.String,
},
"content": &graphql.Field{
Type: graphql.String,
},
},
})
// 處理查詢請求,擷取文章清單
var queryArticles = graphql.Field{
Name: "QueryArticles",
Description: "Query Article List",
Type: graphql.NewList(articleType),
// 無需處理參數
// Resolve是一個處理請求的函數,具體處理邏輯可在此進行
Resolve: func(p graphql.ResolveParams) (result interface{}, err error) {
// 調用Article的models裡面的方法查詢資料
result = models.GetAllArticles()
return result, nil
},
}
// 查詢單篇文章
var queryArticle = graphql.Field{
Name: "QueryArticle",
Description: "Query Article",
Type: articleType,
// Args是定義在GraphQL查詢中支援的查詢字段,
// 可自行随意定義,如加上limit,start這類
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.Int,
},
},
// Resolve是一個處理請求的函數,具體處理邏輯可在此進行
Resolve: func(p graphql.ResolveParams) (result interface{}, err error) {
// Args裡面定義的字段在p.Args裡面,對應的取出來
// 因為是interface{}的值,需要類型轉換
id, ok := p.Args["id"].(int)
if !ok {
return nil, errors.New("missing required arguments: id. ")
}
result, err = models.GetArticleByID(id)
// 調用Hello這個model裡面的Query方法查詢資料
return result, err
},
}
// 定義根查詢節點及各種查詢
var rootQuery = graphql.NewObject(graphql.ObjectConfig{
Name: "RootQuery",
Description: "Root Query",
Fields: graphql.Fields{
"articles": &queryArticles, //分别對應前面定義的query
"article": &queryArticle,
},
})
// 定義Schema用于http handler處理
var Schema, _ = graphql.NewSchema(graphql.SchemaConfig{
Query: rootQuery,
Mutation: nil,
})
這個檔案把昨天main.go裡的很多關于graphql的有關内容,都移到這裡.
這裡的兩個query,分别對應了傳回所有文章和單篇文章,特别是單篇文章處理,增加了Args部分,同時增加了Resolve對于如何擷取參數内容.
現在的main.go就變成了這樣:
package main
import (
"fmt"
"graphqldemo/schema"
"net/http"
"github.com/graphql-go/handler"
)
// main
func main() {
h := Register()
http.Handle("/graphql", h)
fmt.Println("Now server is running on port 8080")
http.ListenAndServe(":8080", nil)
}
// 初始化handler
func Register() *handler.Handler {
h := handler.New(&handler.Config{
Schema: &schema.Schema,
Pretty: true,
GraphiQL: true,
})
return h
}
編譯執行後,打開浏覽器,

注意左側的傳參格式,還有最右側的Docs.
graphql的優勢之一來了,再也不用操心swagger了.
到現在為止,我們的目錄結構如下:
除了使用浏覽器,我們還可以使用postman來調試: