Skip to content

Instantly share code, notes, and snippets.

@larryaasen
Created February 25, 2018 14:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save larryaasen/4fc744796e193da0aeeff671d1d3d3d7 to your computer and use it in GitHub Desktop.
Save larryaasen/4fc744796e193da0aeeff671d1d3d3d7 to your computer and use it in GitHub Desktop.
GraphQL sample using neelance/graphql-go and Go (Golang)
/*
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(&params); 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(&params); 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