Skip to content

Commit

Permalink
Ability to inline extraFields configuration. New @goExtraField direct…
Browse files Browse the repository at this point in the history
…ive. (#3076)

* @goExtraField directive added

* docs for @goExtraField added

---------

Co-authored-by: Roman A. Grigorovich <ragrigorov@mts.ru>
  • Loading branch information
atzedus and Roman A. Grigorovich committed May 15, 2024
1 parent 8b4df63 commit de31828
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 4 deletions.
41 changes: 41 additions & 0 deletions codegen/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ func (c *Config) injectTypesFromSchema() error {
SkipRuntime: true,
}

c.Directives["goExtraField"] = DirectiveConfig{
SkipRuntime: true,
}

c.Directives["goField"] = DirectiveConfig{
SkipRuntime: true,
}
Expand Down Expand Up @@ -346,6 +350,43 @@ func (c *Config) injectTypesFromSchema() error {
}
}
}

if efds := schemaType.Directives.ForNames("goExtraField"); len(efds) != 0 {
for _, efd := range efds {
if fn := efd.Arguments.ForName("name"); fn != nil {
extraFieldName := ""
extraField := ModelExtraField{}
if fnv, err := fn.Value.Value(nil); err == nil {
if !c.Models.Exists(schemaType.Name) {
c.Models[schemaType.Name] = TypeMapEntry{
ExtraFields: make(map[string]ModelExtraField),
}
}
extraFieldName = fnv.(string)
}

if t := efd.Arguments.ForName("type"); t != nil {
if tv, err := t.Value.Value(nil); err == nil {
extraField.Type = tv.(string)
}
}

if ot := efd.Arguments.ForName("overrideTags"); ot != nil {
if otv, err := ot.Value.Value(nil); err == nil {
extraField.OverrideTags = otv.(string)
}
}

if d := efd.Arguments.ForName("description"); d != nil {
if dv, err := d.Value.Value(nil); err == nil {
extraField.Description = dv.(string)
}
}

c.Models[schemaType.Name].ExtraFields[extraFieldName] = extraField
}
}
}
}

if schemaType.Kind == ast.Enum && !strings.HasPrefix(schemaType.Name, "__") {
Expand Down
51 changes: 47 additions & 4 deletions docs/content/recipes/extra_fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@
title: "Generation of additional extra fields for internal use"
description: Pass implementation specific fields to the children resolvers without being forced to define your own types for a GraphQL model.
linkTitle: Generated Model Extra Fields
menu: { main: { parent: 'recipes' } }
menu: { main: { parent: "recipes" } }
---

Extra fields allows you to generate additional fields for your models.
These fields can be used at runtime when implementing field resolvers.

## Extending your models

Imagine you have a model named User and you want to extend a generated struct with additional data used in your service.

The schema is:

```graphql
type User {
id: ID!
name: String!
id: ID!
name: String!
}
```

Expand All @@ -29,6 +30,7 @@ models:
Session:
description: "A Session used by this user"
type: "github.com/author/mypkg.Session"
overrideTags: 'xml:"session"'
```

The generated code would look like:
Expand All @@ -40,8 +42,49 @@ type User struct {
ID string
Name string
// A Session used by this user.
Session mypkg.Session
Session mypkg.Session `xml:"session"`
}
```

After these steps you have an extra field for your server implementation and the field is not being exposed to a caller.

### Inline config with directive

To start using it you first need to define it:

```graphql
directive @goExtraField(
name: String!
type: String!
overrideTags: String
description: String
) on OBJECT | INPUT_OBJECT
```

Now you can use these directive when defining types in your schema:

```graphql
type User
@goExtraField(
name: "Session"
type: "github.com/author/mypkg.Session"
description: "A Session used by this user"
overrideTags: "xml:\"session\""
)
@goExtraField(name: "Activated", type: "bool") {
id: ID
name: String
}
```

The generated code would look like:

```go
type User struct {
ID string
Name string
// A Session used by this user.
Session mypkg.Session `xml:"session"`
Activated bool
}
```

0 comments on commit de31828

Please sign in to comment.