crombird/minigen
an ergonomic golang graphql type generator.
get started
(for working with go modules, check out examples
)
one: install minigen
with go get
:
# this will build minigen to your GOPATH/bin (likely $HOME/go)
go get -d github.com/crombird/minigen
two: write your code
package main
// to run minigen on your package, just include a go:generate directive
// that runs minigen with the API endpoint. you can also configure minigen
// with a minigen.yml file (see "configuring minigen")
//go:generate minigen https://api.url
import (
"fmt"
"mypackage/generated"
"github.com/crombird/minigen/client"
)
// minigen pulls fragments, queries, and mutations from your source code
// that are marked with "minigen:generate".
//minigen:generate
const thingFragment = `
fragment ThingFragment on SomeType {
field3
}
`
// you can define fragments separately and concatenate them statically.
// the name of the generated types comes from the operation name.
//minigen:generate
const myQuery = thingFragment + `
query GetThing($arg1: ID!, $arg2: Int) {
field1
field2 {
...ThingFragment
}
}
`
fn main() {
// minigen also ships with an optional client.
// you can use whatever http client or json parser you want.
gqlClient := client.DefaultClient
// minigen generates response types from your queries.
var response generated.GetThingQuery
err := gqlClient.Do(
&client.GraphQLRequest{
Url: "https://api.url",
Query: myQuery,
// minigen also generates variable types.
Variables: generated.GetThingQueryVariables{
Arg1: generated.ID("..."),
Arg2: generated.NewOptionalInt(100)
},
},
&response,
)
if err != nil {
fmt.Println("uh oh, the api threw an error: " + err.Error())
return
}
fmt.Println(response.Field2.Field3)
}
three: generate your models
if you're using //go:generate
, you can run
go generate
you can also run minigen directly, but you'll need a minigen.yml
(see "configuring minigen")
minigen # if you have the minigen binary (from step one)
go run github.com/crombird/minigen # if you use go modules and a "tools.go" file (see examples)
configuring minigen
minigen can be configured with a minigen.yml
file in the current or parent directories.
here's all the things you can configure, but you don't need to set all of them.
# The API endpoint to fetch the schema from.
# You can skip this if you provided a URL in the "go:generate" comment.
url: https://api.crom.avn.sh/graphql
# You can also include any headers that minigen needs to include when making the request.
# The header value supports environment variables.
headers:
Authorization: Bearer ${API_KEY}
# The folders where minigen should pull .go files from.
# A string or an array of strings are supported.
# You can skip this if you're using "go generate".
source:
- ./cmd
- ./api
# The destination folder where the generated file should go.
# You can skip this if you're using "go generate".
target: ./generated
# The package name of the generated file. Defaults to the target folder's name.
# You shouldn't need to change this normally.
package_name: generated
# The file name of the generated file. Defaults to "graphql.go".
file_name: graphql.go
# If the schema has any custom properties, you can define their underlying types here.
# The default type is "string". You can also define external models with a "." separator
scalars:
EpochTime: int32
JSON: encoding/json.RawMessage
# If set, generates helper methods for scalars. In the generated files,
# optional properties are pointers (e.g. *string, *int32). But this can be
# inconvenient when creating input objects with literals.
#
# So, instead of having to write:
# number := 2
# input := generated.ObjectInput { optionalNumber: &number }
# You can just write:
# input := generated.ObjectInput { optionalNumber: generated.IntRef(2) }
#
scalar_ref_helpers: true
# If set, wraps input types using an additional "Nullable..." wrapper for ease
# of use. Using encoding/json's "omitempty", these types can also be used to
# distinguish between null and "missing" for APIs that rely on that distinction.
#
# So, instead of having to write:
# number := 2
# input := generated.ObjectInput { optionalNumber: &number }
# You can just write:
# input := generated.ObjectInput { optionalNumber: generated.NewNullableInt(2) }
#
nullable_input_types: true