Skip to content

Instantly share code, notes, and snippets.

@zaydek-old
Created November 1, 2019 14:49
Show Gist options
  • Save zaydek-old/9c841814aa90a5067256e19d101f4f6e to your computer and use it in GitHub Desktop.
Save zaydek-old/9c841814aa90a5067256e19d101f4f6e to your computer and use it in GitHub Desktop.
package main
import (
"database/sql"
"encoding/json"
"fmt"
"log"
"github.com/graphql-go/graphql"
_ "github.com/lib/pq"
)
type User struct {
UserID string
DisplayName string
Username string
}
type Note struct {
User User
UserID string
NoteID string
Title string
Data string
}
var userType = graphql.NewObject(
graphql.ObjectConfig{
Name: "User",
Fields: graphql.Fields{
"userID": &graphql.Field{
Type: graphql.String,
},
"displayName": &graphql.Field{
Type: graphql.String,
},
"username": &graphql.Field{
Type: graphql.String,
},
},
},
)
var noteType = graphql.NewObject(
graphql.ObjectConfig{
Name: "Note",
Fields: graphql.Fields{
"user": &graphql.Field{
Type: userType,
},
"userID": &graphql.Field{
Type: graphql.String,
},
"noteID": &graphql.Field{
Type: graphql.String,
},
"title": &graphql.Field{
Type: graphql.String,
},
"data": &graphql.Field{
Type: graphql.String,
},
},
},
)
var fields = graphql.Fields{
// List users:
"users": &graphql.Field{
Description: "List users.",
Type: graphql.NewList(userType),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
var users []User
rows, err := db.Query("select user_id, display_name, username from users")
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var user User
err := rows.Scan(&user.UserID, &user.DisplayName, &user.Username)
if err != nil {
return nil, err
}
users = append(users, user)
}
err = rows.Err()
if err != nil {
return nil, err
}
return users, nil
},
},
// Get user by ID:
"user": &graphql.Field{
Description: "Get user by ID.",
Type: userType,
Args: graphql.FieldConfigArgument{
"userID": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
userID := p.Args["userID"].(string)
var user User
err := db.QueryRow("select user_id, display_name, username from users where user_id = $1", userID).Scan(&user.UserID, &user.DisplayName, &user.Username)
if err != nil {
return nil, err
}
return user, nil
},
},
// List notes:
"notes": &graphql.Field{
Description: "List notes.",
Type: graphql.NewList(noteType),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
var notes []Note
rows, err := db.Query("select user_id, note_id, title, data from notes")
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var note Note
err := rows.Scan(&note.UserID, &note.NoteID, &note.Title, &note.Data)
if err != nil {
return nil, err
}
notes = append(notes, note)
}
err = rows.Err()
if err != nil {
return nil, err
}
return notes, nil
},
},
// Get note by ID:
"note": &graphql.Field{
Description: "Get note by ID.",
Type: noteType,
Args: graphql.FieldConfigArgument{
"noteID": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
noteID := p.Args["noteID"].(string)
var note Note
err := db.QueryRow("select user_id, note_id, title, data from notes where note_id = $1", noteID).Scan(&note.UserID, &note.NoteID, &note.Title, &note.Data)
if err != nil {
return nil, err
}
return note, nil
},
},
}
var schema graphql.Schema
func init() {
log.SetFlags(0)
schemaConfig := graphql.SchemaConfig{
Query: graphql.NewObject(
graphql.ObjectConfig{
Name: "QueryRoot",
Fields: fields,
},
),
}
var err error
schema, err = graphql.NewSchema(schemaConfig)
check(err)
}
func check(err error) {
if err != nil {
log.Fatal(err)
}
}
var db *sql.DB
// { type: new graphql.NonNull(graphql.String) }
func main() {
var err error
db, err = sql.Open("postgres", "postgres://zaydek@localhost/graphql?sslmode=disable")
check(err)
err = db.Ping()
check(err)
defer db.Close()
query := `{
notes {
user(userID: userID) {
userID
displayName
username
}
userID
noteID
title
data
}
}`
params := graphql.Params{Schema: schema, RequestString: query}
result := graphql.Do(params)
if len(result.Errors) > 0 {
check(result.Errors[0])
}
json, err := json.MarshalIndent(result, "", "\t")
check(err)
fmt.Printf("%s \n", json)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment