99designs / 99designs/gqlgen

gqlgen fails when there are several @link directives

Open
#3,398 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
10.8k
Forks
1.3k
Avg merge
2d 36m
Merged PRs (30d)
26

Description

### What happened?

gqlgen 0.17.57 fails to run on my schema with the following stack trace:
```log
panic: runtime error: index out of range [1] with length 0

goroutine 1 [running]:
github.com/99designs/gqlgen/api.Generate(0xc000149688, {0x0, 0x0, 0xeaf0385?})
//go/pkg/mod/github.com/99designs/gqlgen@v0.17.57/api/generate.go:41 +0x1533
main.init.func2(0xc0001c0bc0?)
//go/pkg/mod/github.com/99designs/gqlgen@v0.17.57/main.go:190 +0x9c
github.com/urfave/cli/v2.(*Command).Run(0xc00018c580, 0xc0001c0bc0, {0xc0000220f0, 0x3, 0x3})
//go/pkg/mod/github.com/urfave/cli/v2@v2.27.5/command.go:276 +0x7e2
github.com/urfave/cli/v2.(*App).RunContext(0xc000140400, {0xf14baa0, 0xf4f9700}, {0xc0000220f0, 0x3, 0x3})
//go/pkg/mod/github.com/urfave/cli/v2@v2.27.5/app.go:333 +0x5a5
github.com/urfave/cli/v2.(*App).Run(...)
//go/pkg/mod/github.com/urfave/cli/v2@v2.27.5/app.go:307
main.main()
//go/pkg/mod/github.com/99designs/gqlgen@v0.17.57/main.go:227 +0x20b
```

This is caused by the use of two `@link` directives:
```graphql
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@shareable", "@composeDirective"])
@link(url: "https://.com", import: ["@owner", "@experimental"])
@composeDirective(name: "@owner")
@composeDirective(name: "@experimental")
```

Using multiple `@link` directives is required by the use of `@composeDirective` (following instructions from [Apollo's documentation](https://www.apollographql.com/docs/graphos/reference/federation/directives#managing-custom-directives)).

As a workaround, we can add the following to gqlgen's YAML configuration:
```yaml
federation:
version: 2
```

### What did you expect?

The issue comes from the regular expression `(?s)@link.*\(.*url:.*?"(.*?)"[^)]+\)` that is used by gqlgen to "guess" the Apollo Federation version.

This regular expression is too "broad" and matches everything between the beginning of the first `@link` directive and the end of the last `@link` directive:
```graphql
@link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@shareable", "@composeDirective"])
@link(url: "https://.com", import: ["@owner", "@experimental"])
```

I suggest to use a regular expression that matches the official link URL: `https://specs.apollo.dev/federation/v(\d+)\.(\d+)`.

### Minimal graphql.schema and models to reproduce

See example schema above.

### versions
- `go run github.com/99designs/gqlgen version`? `v0.17.57`
- `go version`? `go version go1.23.3 darwin/amd64`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.