How to do it...

These steps cover writing and running your application:

  1. From your Terminal or console application, create a new directory called ~/projects/go-programming-cookbook/chapter12/graphql and navigate to this directory.
  2. Run this command:
$ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter12/graphql

You should see a file called go.mod that contains the following:

module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter12/graphql   
  1. Copy the tests from ~/projects/go-programming-cookbook-original/chapter12/graphql, or use this as an exercise to write some of your own code!
  1. Create and navigate to the cards directory.
  2. Create a file called card.go with the following content:
        package cards

// Card represents a standard playing
// card
type Card struct {
Value string
Suit string
}

var cards []Card

func init() {
cards = []Card{
{"A", "Spades"}, {"2", "Spades"}, {"3", "Spades"},
{"4", "Spades"}, {"5", "Spades"}, {"6", "Spades"},
{"7", "Spades"}, {"8", "Spades"}, {"9", "Spades"},
{"10", "Spades"}, {"J", "Spades"}, {"Q", "Spades"},
{"K", "Spades"},
{"A", "Hearts"}, {"2", "Hearts"}, {"3", "Hearts"},
{"4", "Hearts"}, {"5", "Hearts"}, {"6", "Hearts"},
{"7", "Hearts"}, {"8", "Hearts"}, {"9", "Hearts"},
{"10", "Hearts"}, {"J", "Hearts"}, {"Q", "Hearts"},
{"K", "Hearts"},
{"A", "Clubs"}, {"2", "Clubs"}, {"3", "Clubs"},
{"4", "Clubs"}, {"5", "Clubs"}, {"6", "Clubs"},
{"7", "Clubs"}, {"8", "Clubs"}, {"9", "Clubs"},
{"10", "Clubs"}, {"J", "Clubs"}, {"Q", "Clubs"},
{"K", "Clubs"},
{"A", "Diamonds"}, {"2", "Diamonds"}, {"3",
"Diamonds"},
{"4", "Diamonds"}, {"5", "Diamonds"}, {"6",
"Diamonds"},
{"7", "Diamonds"}, {"8", "Diamonds"}, {"9",
"Diamonds"},
{"10", "Diamonds"}, {"J", "Diamonds"}, {"Q",
"Diamonds"},
{"K", "Diamonds"},
}
}
  1. Create a file called type.go with the following content:
        package cards

import "github.com/graphql-go/graphql"

// CardType returns our card graphql object
func CardType() *graphql.Object {
cardType := graphql.NewObject(graphql.ObjectConfig{
Name: "Card",
Description: "A Playing Card",
Fields: graphql.Fields{
"value": &graphql.Field{
Type: graphql.String,
Description: "Ace through King",
Resolve: func(p graphql.ResolveParams)
(interface{}, error) {
if card, ok := p.Source.(Card); ok {
return card.Value, nil
}
return nil, nil
},
},
"suit": &graphql.Field{
Type: graphql.String,
Description: "Hearts, Diamonds, Clubs, Spades",
Resolve: func(p graphql.ResolveParams)
(interface{}, error) {
if card, ok := p.Source.(Card); ok {
return card.Suit, nil
}
return nil, nil
},
},
},
})
return cardType
}
  1. Create a file called resolve.go with the following content:
        package cards

import (
"strings"

"github.com/graphql-go/graphql"
)

// Resolve handles filtering cards
// by suit and value
func Resolve(p graphql.ResolveParams) (interface{}, error) {
finalCards := []Card{}
suit, suitOK := p.Args["suit"].(string)
suit = strings.ToLower(suit)

value, valueOK := p.Args["value"].(string)
value = strings.ToLower(value)

for _, card := range cards {
if suitOK && suit != strings.ToLower(card.Suit) {
continue
}
if valueOK && value != strings.ToLower(card.Value) {
continue
}

finalCards = append(finalCards, card)
}
return finalCards, nil
}
  1. Create a file called schema.go with the following content:
        package cards

import "github.com/graphql-go/graphql"

// Setup prepares and returns our card
// schema
func Setup() (graphql.Schema, error) {
cardType := CardType()

// Schema
fields := graphql.Fields{
"cards": &graphql.Field{
Type: graphql.NewList(cardType),
Args: graphql.FieldConfigArgument{
"suit": &graphql.ArgumentConfig{
Description: "Filter cards by card suit
(hearts, clubs, diamonds, spades)",
Type: graphql.String,
},
"value": &graphql.ArgumentConfig{
Description: "Filter cards by card
value (A-K)",
Type: graphql.String,
},
},
Resolve: Resolve,
},
}

rootQuery := graphql.ObjectConfig{Name: "RootQuery",
Fields: fields}
schemaConfig := graphql.SchemaConfig{Query:
graphql.NewObject(rootQuery)}
schema, err := graphql.NewSchema(schemaConfig)

return schema, err
}
  1. Navigate back to the graphql directory.
  2. Create a new directory named example and navigate to it.
  3. Create a file named main.go with the following content:
        package main

import (
"encoding/json"
"fmt"
"log"

"github.com/PacktPublishing/
Go-Programming-Cookbook-Second-Edition/
chapter12/graphql/cards"
"github.com/graphql-go/graphql"
)

func main() {
// grab our schema
schema, err := cards.Setup()
if err != nil {
panic(err)
}

// Query
query := `
{
cards(value: "A"){
value
suit
}
}`

params := graphql.Params{Schema: schema, RequestString:
query}
r := graphql.Do(params)
if len(r.Errors) > 0 {
log.Fatalf("failed to execute graphql operation,
errors: %+v", r.Errors)
}
rJSON, err := json.MarshalIndent(r, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("%s ", rJSON)
}
  1. Run go run main.go.
  2. You may also run the following command:
$ go build
$ ./example

You should see the following output:

$ go run main.go
{
"data": {
"cards": [
{
"suit": "Spades",
"value": "A"
},
{
"suit": "Hearts",
"value": "A"
},
{
"suit": "Clubs",
"value": "A"
},
{
"suit": "Diamonds",
"value": "A"
}
]
}
}
  1. Test some additional queries, such as the following:
    • cards(suit: "Spades")
    • cards(value: "3", suit:"Diamonds")
  2. The go.mod file may be updated, and the go.sum file should now be present in the top-level recipe directory.
  3. If you have copied or written your own tests, go up one directory and run go test. Ensure that all the tests pass.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.19.30.232