diff --git a/README.md b/README.md index d40c9bee0fc..68d879c1042 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ [gqlgen](https://github.com/99designs/gqlgen) is a Go library for building GraphQL servers without any fuss. gqlgen is: - - **Schema first** — Define your API using the GraphQL [Schema Definition Language](http://graphql.org/learn/schema/). - - **Type safe** — You should never see `map[string]interface{}` here. - - **Codegen** — Let us generate the boring bits, so you can build your app quickly. +- **Schema first** — Define your API using the GraphQL [Schema Definition Language](http://graphql.org/learn/schema/). +- **Type safe** — You should never see `map[string]interface{}` here. +- **Codegen** — Let us generate the boring bits, so you can build your app quickly. [Feature Comparison](https://gqlgen.com/feature-comparison/) @@ -29,20 +29,22 @@ Read our [Contribution Guidelines](https://github.com/99designs/gqlgen/blob/mast ### How do I prevent fetching child objects that might not be used? When you have nested or recursive schema like this: + ```graphql type User { - id: ID! - name: String! - friends: [User!]! + id: ID! + name: String! + friends: [User!]! } ``` + You need to tell gqlgen that we should only fetch friends if the user requested it. There are two ways to do this. 1. Write the model yourself and leave off friends. ```go type User struct { - Id int + ID int Name string } ``` @@ -66,6 +68,7 @@ models: ``` After doing either of the above and running generate we will need to provide a resolver for friends: + ```go func (r *userResolver) Friends(ctx context.Context, obj *User) ([]*User, error) { // select * from user where friendid = obj.ID @@ -76,23 +79,25 @@ func (r *userResolver) Friends(ctx context.Context, obj *User) ([]*User, error) ### IDs are strings but I like ints, why cant I have ints? You can by remapping it in config: + ```yaml models: ID: # The GraphQL type ID is backed by model: - - github.com/99designs/gqlgen/graphql.IntID # An go integer - - github.com/99designs/gqlgen/graphql.ID # or a go string + - github.com/99designs/gqlgen/graphql.IntID # An go integer + - github.com/99designs/gqlgen/graphql.ID # or a go string ``` This means gqlgen will be able to automatically bind to strings or ints for models you have written yourself, but the first model in this list is used as the default type and it will always be used when: - - generating models based on schema - - as arguments in resolvers + +- generating models based on schema +- as arguments in resolvers There isnt any way around this, gqlgen has no way to know what you want in a given context. ## Other Resources - - [Christopher Biscardi @ Gophercon UK 2018](https://youtu.be/FdURVezcdcw) - - [Introducing gqlgen: a GraphQL Server Generator for Go](https://99designs.com.au/blog/engineering/gqlgen-a-graphql-server-generator-for-go/) - - [Dive into GraphQL by Iván Corrales Solera](https://medium.com/@ivan.corrales.solera/dive-into-graphql-9bfedf22e1a) +- [Christopher Biscardi @ Gophercon UK 2018](https://youtu.be/FdURVezcdcw) +- [Introducing gqlgen: a GraphQL Server Generator for Go](https://99designs.com.au/blog/engineering/gqlgen-a-graphql-server-generator-for-go/) +- [Dive into GraphQL by Iván Corrales Solera](https://medium.com/@ivan.corrales.solera/dive-into-graphql-9bfedf22e1a) diff --git a/docs/content/reference/file-upload.md b/docs/content/reference/file-upload.md index 116bc4f7a4e..0680d62fef1 100644 --- a/docs/content/reference/file-upload.md +++ b/docs/content/reference/file-upload.md @@ -1,29 +1,32 @@ --- -title: 'File Upload' +title: "File Upload" description: How to upload files. linkTitle: File Upload -menu: { main: { parent: 'reference' } } +menu: { main: { parent: "reference" } } --- Graphql server has an already built-in Upload scalar to upload files using a multipart request. \ -It implements the following spec https://github.com/jaydenseric/graphql-multipart-request-spec, -that defines an interoperable multipart form field structure for GraphQL requests, used by -various file upload client implementations. +It implements the following spec https://github.com/jaydenseric/graphql-multipart-request-spec, +that defines an interoperable multipart form field structure for GraphQL requests, used by +various file upload client implementations. To use it you need to add the Upload scalar in your schema, and it will automatically add the marshalling behaviour to Go types. # Configuration + There are two specific options that can be configured for uploading files: + - uploadMaxSize \ -This option specifies the maximum number of bytes used to parse a request body as multipart/form-data. + This option specifies the maximum number of bytes used to parse a request body as multipart/form-data. - uploadMaxMemory \ -This option specifies the maximum number of bytes used to parse a request body as -multipart/form-data in memory, with the remainder stored on disk in temporary files. + This option specifies the maximum number of bytes used to parse a request body as + multipart/form-data in memory, with the remainder stored on disk in temporary files. # Examples ## Single file upload + For this use case, the schema could look like this. ```graphql @@ -41,7 +44,8 @@ type Mutation { } ``` -cURL can be used the make a query as follows: +cURL can be used the make a query as follows: + ``` curl localhost:4000/graphql \ -F operations='{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }' \ @@ -50,7 +54,8 @@ curl localhost:4000/graphql \ ``` That invokes the following operation: -``` + +```graphql { query: ` mutation($file: Upload!) { @@ -66,8 +71,9 @@ That invokes the following operation: ``` ## Multiple file upload + For this use case, the schema could look like this. - + ```graphql "The `Upload` scalar type represents a multipart file upload." scalar Upload @@ -97,9 +103,9 @@ type Mutation { ``` -cURL can be used the make a query as follows: +cURL can be used the make a query as follows: -``` +```bash curl localhost:4000/query \ -F operations='{ "query": "mutation($req: [UploadFile!]!) { multipleUpload(req: $req) { id, name, content } }", "variables": { "req": [ { "id": 1, "file": null }, { "id": 2, "file": null } ] } }' \ -F map='{ "0": ["variables.req.0.file"], "1": ["variables.req.1.file"] }' \ @@ -108,7 +114,8 @@ curl localhost:4000/query \ ``` That invokes the following operation: -``` + +```graphql { query: ` mutation($req: [UploadFile!]!) @@ -129,7 +136,7 @@ That invokes the following operation: id: 2, File, // c.txt } - ] + ] } } ``` diff --git a/docs/content/reference/plugins.md b/docs/content/reference/plugins.md index 7f8cfce0b0b..047da75c884 100644 --- a/docs/content/reference/plugins.md +++ b/docs/content/reference/plugins.md @@ -2,14 +2,14 @@ linkTitle: Plugins title: How to write plugins for gqlgen description: Use plugins to customize code generation and integrate with other libraries -menu: { main: { parent: 'reference' } } +menu: { main: { parent: "reference" } } --- Plugins provide a way to hook into the gqlgen code generation lifecycle. In order to use anything other than the default plugins you will need to create your own entrypoint: - ## Using a plugin + ```go // +build ignore @@ -36,7 +36,7 @@ func main() { } - err = api.Generate(cfg, + err = api.Generate(cfg, api.AddPlugin(yourplugin.New()), // This is the magic line ) if err != nil { @@ -45,18 +45,17 @@ func main() { } } -``` +``` ## Writing a plugin There are currently only two hooks: - - MutateConfig: Allows a plugin to mutate the config before codegen starts. This allows plugins to add - custom directives, define types, and implement resolvers. see - [modelgen](https://github.com/99designs/gqlgen/tree/master/plugin/modelgen) for an example - - GenerateCode: Allows a plugin to generate a new output file, see - [stubgen](https://github.com/99designs/gqlgen/tree/master/plugin/stubgen) for an example - -Take a look at [plugin.go](https://github.com/99designs/gqlgen/blob/master/plugin/plugin.go) for the full list of -available hooks. These are likely to change with each release. +- MutateConfig: Allows a plugin to mutate the config before codegen starts. This allows plugins to add + custom directives, define types, and implement resolvers. see + [modelgen](https://github.com/99designs/gqlgen/tree/master/plugin/modelgen) for an example +- GenerateCode: Allows a plugin to generate a new output file, see + [stubgen](https://github.com/99designs/gqlgen/tree/master/plugin/stubgen) for an example +Take a look at [plugin.go](https://github.com/99designs/gqlgen/blob/master/plugin/plugin.go) for the full list of +available hooks. These are likely to change with each release. diff --git a/docs/content/reference/scalars.md b/docs/content/reference/scalars.md index 02ea1fb7aa0..99d25d32304 100644 --- a/docs/content/reference/scalars.md +++ b/docs/content/reference/scalars.md @@ -2,12 +2,12 @@ linkTitle: Scalars title: Mapping GraphQL scalar types to Go types description: Mapping GraphQL scalar types to Go types -menu: { main: { parent: 'reference' } } +menu: { main: { parent: "reference" } } --- ## Built-in helpers -gqlgen ships with three built-in helpers for common custom scalar use-cases, `Time`, `Any`, `Upload` and `Map`. Adding any of these to a schema will automatically add the marshalling behaviour to Go types. +gqlgen ships with three built-in helpers for common custom scalar use-cases, `Time`, `Any`, `Upload` and `Map`. Adding any of these to a schema will automatically add the marshalling behaviour to Go types. ### Time @@ -32,13 +32,15 @@ scalar Upload ``` Maps a `Upload` GraphQL scalar to a `graphql.Upload` struct, defined as follows: -``` + +```go type Upload struct { File io.Reader Filename string Size int64 } ``` + ### Any ```graphql @@ -47,7 +49,7 @@ scalar Any Maps an arbitrary GraphQL value to a `interface{}` Go type. -## Custom scalars with user defined types +## Custom scalars with user defined types For user defined types you can implement the graphql.Marshaler and graphql.Unmarshaler interfaces and they will be called. @@ -88,13 +90,13 @@ func (y YesNo) MarshalGQL(w io.Writer) { ``` and then in .gqlgen.yml point to the name without the Marshal|Unmarshal in front: + ```yaml models: YesNo: model: github.com/me/mypkg.YesNo ``` - ## Custom scalars with third party types Sometimes you cant add methods to a type because its in another repo, part of the standard @@ -136,11 +138,12 @@ func UnmarshalMyCustomBooleanScalar(v interface{}) (bool, error) { } ``` -and then in .gqlgen.yml point to the name without the Marshal|Unmarshal in front: +Then in .gqlgen.yml point to the name without the Marshal|Unmarshal in front: + ```yaml models: MyCustomBooleanScalar: model: github.com/me/mypkg.MyCustomBooleanScalar ``` -see the [example/scalars](https://github.com/99designs/gqlgen/tree/master/example/scalars) package for more examples. +See the [example/scalars](https://github.com/99designs/gqlgen/tree/master/example/scalars) package for more examples.