Created
February 25, 2018 14:32
-
-
Save larryaasen/4fc744796e193da0aeeff671d1d3d3d7 to your computer and use it in GitHub Desktop.
GraphQL sample using neelance/graphql-go and Go (Golang)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Examples: | |
http://localhost:8080/graphql?query={person(id:1000){id firstName lastName}} | |
http://localhost:8080/graphql?query={person(id:"1000"){id}} | |
*/ | |
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
graphql "github.com/neelance/graphql-go" | |
"log" | |
"net/http" | |
// "github.com/neelance/graphql-go/relay" | |
"net/url" | |
// "strings" | |
) | |
// var Schema = ` | |
// schema { | |
// query: Query | |
// } | |
// type Person { | |
// id: ID! | |
// firstName: String! | |
// lastName: String | |
// } | |
// type Query { | |
// person(id: ID!): Person | |
// } | |
// ` | |
var Schema = ` | |
schema { | |
query: Query | |
} | |
type Person { | |
id: ID! | |
firstName: String! | |
lastName: String | |
} | |
type Query { | |
person: Person | |
} | |
` | |
type person struct { | |
ID graphql.ID | |
FirstName string | |
LastName string | |
} | |
var people = []*person{ | |
{ | |
ID: "1000", | |
FirstName: "Pedro", | |
LastName: "Marquez", | |
}, | |
{ | |
ID: "1001", | |
FirstName: "John", | |
LastName: "Doe", | |
}, | |
} | |
type personResolver struct { | |
p *person | |
} | |
func (r *personResolver) ID() graphql.ID { | |
return r.p.ID | |
} | |
func (r *personResolver) FirstName() string { | |
return r.p.FirstName | |
} | |
func (r *personResolver) LastName() *string { | |
return &r.p.LastName | |
} | |
type Resolver struct{} | |
// func (r *Resolver) Person(args struct{ ID graphql.ID }) *personResolver { | |
// log.Print("personResolver: start\n") | |
// if p := peopleData[args.ID]; p != nil { | |
// log.Print("Found in resolver!\n") | |
// return &personResolver{p} | |
// } | |
// log.Print("personResolver: end\n") | |
// return nil | |
// } | |
func (r *Resolver) Person() []*personResolver { | |
log.Print("personResolver: start\n") | |
p := people[0] | |
people := make([]*personResolver, 0) | |
people = append(people, &personResolver{p}) | |
log.Print("personResolver: end\n") | |
return people | |
} | |
var peopleData = make(map[graphql.ID]*person) | |
var mainSchema *graphql.Schema | |
type MyHandler struct { | |
Schema *graphql.Schema | |
} | |
func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |
fmt.Printf("ServeHTTP: start\n") | |
var params struct { | |
Query string `json:"query"` | |
OperationName string `json:"operationName"` | |
Variables map[string]interface{} `json:"variables"` | |
} | |
if r.Method == "GET" && len(r.URL.Query()) > 0 { | |
fmt.Printf("ServeHTTP: parse query\n") | |
u, _ := url.Parse(r.URL.String()) | |
queryParams := u.Query() | |
fmt.Printf("ServeHTTP: parse queryParams: %v\n", queryParams) | |
query := queryParams["query"] | |
fmt.Printf("ServeHTTP: parse query: %v\n", query) | |
queryString := "" | |
if len(query) > 0 { | |
queryString = query[0] | |
fmt.Printf("ServeHTTP: queryString: %v\n", queryString) | |
} | |
params.Query = queryString | |
// q := r.URL.Query | |
// fmt.Printf("ServeHTTP: parse q: %v\n", q) | |
// if err := json.NewDecoder(strings.NewReader(queryString)).Decode(¶ms); err != nil { | |
// fmt.Printf("ServeHTTP: error %v\n", err) | |
// http.Error(w, err.Error(), http.StatusBadRequest) | |
// return | |
// } | |
} else { | |
fmt.Printf("ServeHTTP: parse body\n") | |
if err := json.NewDecoder(r.Body).Decode(¶ms); err != nil { | |
fmt.Printf("ServeHTTP: error %v\n", err) | |
http.Error(w, err.Error(), http.StatusBadRequest) | |
return | |
} | |
} | |
fmt.Printf("ServeHTTP: params %v\n", params) | |
response := h.Schema.Exec(r.Context(), params.Query, params.OperationName, params.Variables) | |
fmt.Printf("ServeHTTP: response %v\n", response) | |
responseJSON, err := json.Marshal(response) | |
if err != nil { | |
fmt.Printf("ServeHTTP: Marshal error %v\n", err) | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
w.Header().Set("Content-Type", "application/json") | |
w.Write(responseJSON) | |
fmt.Print("ServeHTTP: end\n") | |
} | |
func init() { | |
for _, p := range people { | |
peopleData[p.ID] = p | |
} | |
mainSchema = graphql.MustParseSchema(Schema, &Resolver{}) | |
} | |
func main() { | |
http.Handle("/graphql", &MyHandler{Schema: mainSchema}) | |
log.Print("Starting to listen 8080...") | |
log.Fatal(http.ListenAndServe(":8080", nil)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment