gcg

package module
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 17, 2022 License: MIT Imports: 13 Imported by: 0

README

gcg - graphql client generator

This tool takes a GraphQL schema in SDL and generates Go sources for all entities (enums, mutations, types, queries, unions, functions).

The generated types can be used both for composing GraphQL queries and populating response data. Queries and mutations are composed by setting field values in your (nested) structure to a non-zero value. If you need more complex queries than can not be expressed using the types then you can choose to use the types only for capturing the response.

Generated sources have no dependencies outside the standard Go SDK.

status

work in progress

prepare

Create a configuration file schema-generate.yaml with the following contents:

# the Go package name for the generated files
package: tweet

# the GraphQL schema in SDL (use a converter if you have JSON)
schema: schema.gql

# optionally, map Scalar to your own implementation
bindings:
	Date: CustomDate

run

go run github.com/emicklei/graphql-client-gen/cmd/gcg
gofmt -w enums.go
gofmt -w mutations.go
gofmt -w types.go
gofmt -w scalars.go
gofmt -w queries.go
gofmt -w unions.go
gofmt -w functions.go
gofmt -w build.go

usage

Schema example (SDL):

type Tweet {
	id: ID!
	body: String
	Responders(limit:Int!):[User!]
}
type Query {
	Tweets(limit: Int, skip: Int, sort_field: String, sort_order: String): [Tweet]
}
type Mutation {
	createTweet (body: String): Tweet	
}

With generated Go code from this schema, you can write queries and mutations.

Create example:

m := CreateTweetMutation{}

// set non-zero value to mark the field as part of query
m.Data.ID = "?"

// build GraphQLRequest with query,operation and variables
r := m.Build("hello")

Results in query:

mutation createTweet($body:String) {
	createTweet(body: $body) {
		id
	}
}

Read Tweet ID from response

// use the CreateTweetMutation to capture the data
json.Unmarshal(responseBytes, &m)
id := m.Data.ID

Read example:

q := TweetsQuery{}
q.Data = []TweetsQueryData{
	{
		Tweet: Tweet{ID: "?"},
	},
}
r := q.Build("testTweets", 1, 0, "id", "desc")

Results in query

query testTweets($limit:Int,$skip:Int,$sort_field:String,$sort_order:String) {
	Tweets(limit: $limit,skip: $skip,sort_field: $sort_field,sort_order: $sort_order) {
		id
	}
}

Read Tweet ID from response

// use the TweetsQuery to capture the data
json.Unmarshal(responseBytes, &q)
id := q.Data.Tweets[0].ID

how to post a GraphQLRequest

request := aQueryOrMutation.Build(....)
requestBytes, err := json.Marshal(request)
requestReader := bytes.NewReader(requestBytes)

// if you need to pass headers then use http.NewRequest instead
resp , err = http.Post("http://your.service/api", "application/json", requestReader)

inject the schema version

Using a directive, you can provide version information about the schema. The following example shows how to define this

directive @version(name:String="dev") on SCHEMA

schema @version(name:"v1.0.0") {
	query: Query
	mutation: Mutation
}

Then the generator will initialize a constant in queries.go such as:

const SchemaVersion = "v1.0.0"
todo
  • make optional arguments for function
  • __typename meta field
  • inputs with null values

limitations

Unsupported GraphQL features are:

  • inline fragments
  • directives
  • default values

© 2022+, ernestmicklei.com. MIT License. Contributions welcome.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func WithPackage

func WithPackage(name string) func(*Generator)

func WithScalarBindings

func WithScalarBindings(bindings map[string]string) func(*Generator)

func WithSource added in v0.2.0

func WithSource(filename string) func(*Generator)

Types

type Argument

type Argument struct {
	Name      string
	JSONName  string
	Type      string
	GraphType string
	IsArray   bool
}

type EnumData

type EnumData struct {
	Comment string
	Name    string
	Values  []string
}

type Errors

type Errors struct {
	Message   string `json:"message,omitempty"`
	Locations []struct {
		Line   int `json:"line"`
		Column int `json:"column"`
	} `json:"locations,omitempty"`
	Extensions map[string]interface{} `json:"extensions,omitempty"`
}

Errors is a response field to capture server reported problems

type FieldData

type FieldData struct {
	StructName string
	Comment    string
	Name       string
	JSONName   string
	Tag        string
	Type       string
	IsArray    bool
	Optional   bool
}

type FileData

type FileData struct {
	Package         string
	BuildVersion    string
	Types           []TypeData
	Enums           []EnumData
	Mutations       []OperationData
	Queries         []OperationData
	Scalars         []ScalarData
	Functions       []FunctionData
	Unions          []UnionData
	Inputs          []InputData
	IncludeScalarID bool
	SchemaVersion   string
}

type Function

type Function struct {
	Signature   string
	Type        string
	Description string
	Arguments   ast.ArgumentDefinitionList
	IsArray     bool
	ReturnType  string
	Tag         string
}

type FunctionData

type FunctionData struct {
	Comment    string
	Name       string
	Fields     []FieldData
	IsArray    bool
	ReturnType string
	ResultTag  string
}

type Generator

type Generator struct {
	// contains filtered or unexported fields
}

func NewGenerator

func NewGenerator(schemaSource string, options ...Option) *Generator

func (*Generator) Generate

func (g *Generator) Generate() error

type GraphQLRequest

type GraphQLRequest struct {
	Query         string                 `json:"query"`
	OperationName string                 `json:"operationName"`
	Variables     map[string]interface{} `json:"variables"`
}

GraphQLRequest is used to model both a query or a mutation request

Example
request := GraphQLRequest{}
requestBytes, _ := json.Marshal(request)
requestReader := bytes.NewReader(requestBytes)
_, _ = http.Post("http://your.service/api", "application/json", requestReader)
Output:

func NewGraphQLRequest

func NewGraphQLRequest(query, operation string, vars ...map[string]interface{}) GraphQLRequest

NewGraphQLRequest returns a new Request (for query or mutation) with optional or empty variables.

type InputData added in v0.3.0

type InputData struct {
	Comment string
	Name    string
	Fields  []FieldData
}

type OperationData

type OperationData struct {
	Comment         string
	Definition      string
	Name            string
	FunctionName    string
	Arguments       []Argument
	ReturnType      string
	ReturnFieldName string
	ReturnFieldTag  string
	IsArray         bool
	DataTag         string
	ErrorsTag       string
}

type Option

type Option func(*Generator)

type ScalarBinding

type ScalarBinding struct {
	GraphQLScalar string
	GoTypeName    string
}

type ScalarData

type ScalarData struct {
	Comment string
	Name    string
}

type TypeData

type TypeData struct {
	Comment string
	Kind    string
	Name    string
	Fields  []FieldData
}

type UnionData

type UnionData struct {
	Comment string
	Name    string
	Types   []string
}

Directories

Path Synopsis
cmd
gcg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL