Skip to content

Commit ebf241b

Browse files
committed
Give the example/ directory its own workspace file
This makes it more obvious how to bootstrap a new project with `rules_gqlgen`. Also, clean up the README.md a bit and remove references to "GoLang". Fixes #11
1 parent 03669fd commit ebf241b

File tree

15 files changed

+545
-75
lines changed

15 files changed

+545
-75
lines changed

.bazelignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
example/

.github/workflows/build.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,9 @@ jobs:
2121
path: "~/.cache/bazel"
2222
key: bazel
2323

24-
- run: bazel build //...
24+
- name: Build rules_gqlgen
25+
run: bazel build //...
26+
27+
- name: Build example server
28+
working-directory: ./example
29+
run: bazel build //...

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ bazel-bin
22
bazel-out
33
bazel-testlogs
44
bazel-rules_gqlgen
5+
bazel-example

BUILD.bazel

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
load("@bazel_gazelle//:def.bzl", "gazelle")
22

33
# gazelle:prefix github.com/Silicon-Ally/rules_gqlgen
4-
# gazelle:resolve go github.com/Silicon-Ally/rules_gqlgen/example/generated //example:gql_generated
5-
# gazelle:resolve go github.com/Silicon-Ally/rules_gqlgen/example/model //example:gql_model
64
gazelle(name = "gazelle")
75

86
gazelle(

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,18 @@ The `example` directory provides a basic GraphQL schema and server backed by
4545
`gqlgen`, you can run it with:
4646

4747
```bash
48-
bazel run //example
48+
# example/ is a separate Bazel workspace, so need to enter it first.
49+
cd example
50+
# Run the server on port 8080
51+
bazel run //:example
4952
```
5053

51-
See the the example's README.md for a thorough explanation of what is happening.
54+
See the the [example's README.md](/example/README.md) for a thorough
55+
explanation of what is happening.
56+
57+
## Modifying gqlgen.yml
58+
59+
Currently, `rules_gqlgen` does not support the gqlgen configuration file,
60+
`gqlgen.yml` file, beyond specifying the schema to generate code for. If this
61+
is important to you, or you have specific features in mind that you'd like
62+
supported, file an issue.

WORKSPACE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ http_archive(
2222

2323
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
2424
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
25-
load("//:deps.bzl", "go_dependencies")
25+
load("//:deps.bzl", "gqlgen_dependencies")
2626

2727
# gazelle:repository_macro deps.bzl%go_dependencies
28-
go_dependencies()
28+
gqlgen_dependencies()
2929

3030
go_rules_dependencies()
3131

deps.bzl

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
load("@bazel_gazelle//:deps.bzl", "go_repository")
1+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
2+
load(
3+
"@bazel_gazelle//:deps.bzl",
4+
_go_repository = "go_repository",
5+
)
6+
7+
def go_repository(**kwargs):
8+
_maybe(_go_repository, **kwargs)
9+
10+
def gqlgen_dependencies():
11+
go_dependencies()
212

313
def go_dependencies():
414
go_repository(
515
name = "com_github_99designs_gqlgen",
616
importpath = "github.com/99designs/gqlgen",
7-
sum = "h1:lH/H5dTYCY5eLNRKXeq22l0wFMavpOnN6v9GAIw+fxY=",
8-
version = "v0.17.12",
17+
sum = "h1:ETUEqvRg5Zvr1lXtpoRdj026fzVay0ZlJPwI33qXLIw=",
18+
version = "v0.17.13",
919
)
1020
go_repository(
1121
name = "com_github_agnivade_levenshtein",
@@ -34,8 +44,8 @@ def go_dependencies():
3444
go_repository(
3545
name = "com_github_cpuguy83_go_md2man_v2",
3646
importpath = "github.com/cpuguy83/go-md2man/v2",
37-
sum = "h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=",
38-
version = "v2.0.2",
47+
sum = "h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=",
48+
version = "v2.0.1",
3949
)
4050
go_repository(
4151
name = "com_github_davecgh_go_spew",
@@ -125,8 +135,8 @@ def go_dependencies():
125135
go_repository(
126136
name = "com_github_mitchellh_mapstructure",
127137
importpath = "github.com/mitchellh/mapstructure",
128-
sum = "h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA=",
129-
version = "v1.3.1",
138+
sum = "h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=",
139+
version = "v1.5.0",
130140
)
131141
go_repository(
132142
name = "com_github_pmezard_go_difflib",
@@ -162,14 +172,14 @@ def go_dependencies():
162172
go_repository(
163173
name = "com_github_urfave_cli_v2",
164174
importpath = "github.com/urfave/cli/v2",
165-
sum = "h1:c6bD90aLd2iEsokxhxkY5Er0zA2V9fId2aJfwmrF+do=",
166-
version = "v2.11.0",
175+
sum = "h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=",
176+
version = "v2.8.1",
167177
)
168178
go_repository(
169179
name = "com_github_vektah_gqlparser_v2",
170180
importpath = "github.com/vektah/gqlparser/v2",
171-
sum = "h1:Yjzp66g6oVq93Jihbi0qhGnf/6zIWjcm8H6gA27zstE=",
172-
version = "v2.4.6",
181+
sum = "h1:yub2WLoSIr+chP1zMv6bjrsgTasfubxGZJeC8ISEpgE=",
182+
version = "v2.4.7",
173183
)
174184
go_repository(
175185
name = "com_github_xrash_smetrics",
@@ -235,8 +245,8 @@ def go_dependencies():
235245
go_repository(
236246
name = "org_golang_x_sys",
237247
importpath = "golang.org/x/sys",
238-
sum = "h1:/m5NbqQelATgoSPVC2Z23sR4kVNokFwDDyWh/3rGY+I=",
239-
version = "v0.0.0-20220708085239-5a0f0661e09d",
248+
sum = "h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=",
249+
version = "v0.0.0-20211019181941-9d821ace8654",
240250
)
241251
go_repository(
242252
name = "org_golang_x_term",
@@ -253,12 +263,16 @@ def go_dependencies():
253263
go_repository(
254264
name = "org_golang_x_tools",
255265
importpath = "golang.org/x/tools",
256-
sum = "h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY=",
257-
version = "v0.1.11",
266+
sum = "h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=",
267+
version = "v0.1.10",
258268
)
259269
go_repository(
260270
name = "org_golang_x_xerrors",
261271
importpath = "golang.org/x/xerrors",
262-
sum = "h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0=",
263-
version = "v0.0.0-20220609144429-65e65417b02f",
272+
sum = "h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=",
273+
version = "v0.0.0-20200804184101-5ec99f83aff1",
264274
)
275+
276+
def _maybe(repo_rule, name, **kwargs):
277+
if name not in native.existing_rules():
278+
repo_rule(name = name, **kwargs)

example/.bazelversion

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5.1.0

example/BUILD.bazel

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
11
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
2-
load("//gqlgen:def.bzl", "gqlgen")
2+
load("@rules_gqlgen//gqlgen:def.bzl", "gqlgen")
3+
load("@bazel_gazelle//:def.bzl", "gazelle")
4+
5+
# gazelle:prefix github.com/Silicon-Ally/rules_gqlgen/example
6+
# gazelle:resolve go github.com/Silicon-Ally/rules_gqlgen/example/generated //gql_generated
7+
# gazelle:resolve go github.com/Silicon-Ally/rules_gqlgen/example/model //gql_model
8+
gazelle(name = "gazelle")
9+
10+
gazelle(
11+
name = "gazelle-update-repos",
12+
args = [
13+
"-from_file=go.mod",
14+
"-to_macro=deps.bzl%go_dependencies",
15+
"-prune",
16+
],
17+
command = "update-repos",
18+
)
319

420
gqlgen(
521
name = "gql",
622
base_importpath = "github.com/Silicon-Ally/rules_gqlgen/example",
7-
schemas = [":schema.graphqls"],
23+
schemas = ["//:schema.graphqls"],
824
visibility = ["//visibility:public"],
925
gomod = "//:go.mod",
1026
gosum = "//:go.sum",
@@ -16,8 +32,8 @@ go_library(
1632
importpath = "github.com/Silicon-Ally/rules_gqlgen/example",
1733
visibility = ["//visibility:private"],
1834
deps = [
19-
"//example:gql_generated",
20-
"//example:gql_model",
35+
"//:gql_generated",
36+
"//:gql_model",
2137
"@com_github_99designs_gqlgen//graphql/handler",
2238
"@com_github_99designs_gqlgen//graphql/playground",
2339
],
@@ -28,3 +44,11 @@ go_binary(
2844
embed = [":example_lib"],
2945
visibility = ["//visibility:public"],
3046
)
47+
48+
exports_files([
49+
"go.mod",
50+
"go.sum",
51+
])
52+
53+
exports_files(["schema.graphqls"])
54+

example/README.md

Lines changed: 34 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
# Example Usage
22

3-
This minimal example demonstrates the functionality of this build rule.
3+
This minimal example demonstrates the functionality of the `gqlgen` build rule.
44

5-
To run this you'll need to have [bazel](https://bazel.build/) installed,
6-
and it's also recommended to use [bazelisk](https://github.com/bazelbuild/bazelisk)
7-
to choose a suitable version of bazel to run. We use [gazelle](https://github.com/bazelbuild/bazel-gazelle)
5+
To run this you'll need to have [Bazel](https://bazel.build/) installed,
6+
and it's also recommended to use [Bazelisk](https://github.com/bazelbuild/bazelisk)
7+
to choose a suitable version of bazel to run. We use [Gazelle](https://github.com/bazelbuild/bazel-gazelle)
88
to manage Go dependencies in bazel, but that isn't strictly nescessary.
99

1010
## What is happening?
1111

12-
The input to the build rule is the `schema.graphqls` - a file that describes
13-
the queries and mutations that your GraphQL server is going to offer to clients.
12+
The input to the build rule is the `schema.graphqls`, which describes the
13+
queries and mutations that your GraphQL server is going to serve to clients.
14+
The format of the GraphQL schema file is described in
15+
[the official GraphQL docs](https://graphql.org/learn/).
1416

15-
When you run `bazel build`, this file is taken in, synthesized by a library called
16-
`[gqlgen](https://github.com/99designs/gqlgen)`, and produces two pieces of
17-
GoLang code.
17+
When the rule executes, a [gqlgen.yml](https://gqlgen.com/config/) file is generated, the `gqlgen` code generator tool is run, and two
18+
separate Go libraries are produced, `model` and `generated`.
1819

19-
In the first one, `bazel-bin/example/graph/model/models_gen.go`, the library
20-
has created GoLang package called `model` which contains structs that mirror the
21-
types expressed in your GraphQL schema. This allows you to write business logic
22-
that uses types defined in your schema.
20+
The `model` library consists of `bazel-bin/example/model/models_gen.go`, which
21+
contains the Go structs that mirror the types expressed in your GraphQL schema.
22+
This allows you to write business logic that uses types defined in your schema.
2323

2424
```golang
2525
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
@@ -36,44 +36,45 @@ type UpdateGreetingRequest struct {
3636
}
3737
```
3838

39-
In order to actually implement the business logic of your GraphQL schema, you need
40-
to implement __resolvers__ (GoLang functions that each implement a single
41-
mutation or query in your GQL schema). In `main.go`, this is accomplished by creating
42-
structs which implement these methods. Note how these methods correspond to the
43-
mutations and queries expressed in the schema, and how the types used for inputs/outputs
44-
come from the generated `model` pakage.
39+
The `generated` library consists of `bazel-bin/example/generated/generated.go`,
40+
which contains a generated GraphQL server runtime that can serve your API,
41+
usually over HTTP and/or WebSockets. It handles deserializing and validating
42+
the incoming requests, then calling the correct resolvers, which you'll
43+
implement. For this example, the interface to implement looks like:
4544

46-
```
47-
func (r *queryResolver) Greetings(ctx context.Context) ([]*model.Greeting, error) {
48-
// ...
45+
```go
46+
type ResolverRoot interface {
47+
Mutation() MutationResolver
48+
Query() QueryResolver
4949
}
5050

51-
func (r *mutationResolver) UpdateName(ctx context.Context, req model.UpdateGreetingRequest) (*bool, error) {
52-
//
51+
type MutationResolver interface {
52+
UpdateName(ctx context.Context, req model.UpdateGreetingRequest) (*bool, error)
53+
}
54+
type QueryResolver interface {
55+
Greetings(ctx context.Context) ([]*model.Greeting, error)
5356
}
5457
```
5558

56-
The second output of this build rule can be found in `bazel-bin/example/graph/generated/generated.go`.
57-
It is a generated server runtime in Golang that serves HTTP endpoints that (after layers of validation)
58-
call the resolvers that you've defined. This server can be then be started (using the generated code and
59-
your resolvers to service GraphQL requests over HTTP) by instantiating the server, and passing in the
60-
resolvers, which tell the server how to execute your business logic.
59+
Take a look at [main.go](/example/main.go) to see what a basic `Resolver`
60+
implementation looks like. Then, you can instantiate your server like:
6161

6262
```
6363
import (
6464
"github.com/99designs/gqlgen/graphql/handler"
6565
"github.com/Silicon-Ally/rules_gqlgen/example/generated"
6666
)
6767
68-
...
68+
// ... more setup code ...
6969
srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &Resolver{}}))
70-
...
70+
// ... srv implements http.Handler and can now be used, e.g. via http.ListenAndServe ...
7171
```
7272

7373
## Playground
7474

75-
When you actually run the generated server, it runs on port 8080, and you can access the playground at
76-
`http://localhost:8080/api/playground`.
75+
When you run the example server, it runs on port 8080, and you can access the
76+
playground at `http://localhost:8080/api/playground`. To test the example query
77+
and mutation:
7778

7879
```graphql
7980
# Query greetings
@@ -89,13 +90,3 @@ mutation {
8990
updateName(req:{name:"Moxie"})
9091
}
9192
```
92-
93-
## Tweaking Configuration
94-
95-
Today, you cannot tweak the GQL configuration via a `gqlgen.yml` file (as you can via a vanilla `gqlgen` integration). If this is important to you, or you have specific flags/features in mind that you'd like to contribute, shoot us an email/file a Github Issue.
96-
97-
## Further Reading
98-
99-
This library (`rules_gqlgen`) enables this whole compilation and generation process to happen via
100-
Bazel. The meat of the library is contained in the `[gqlgen](https://github.com/99designs/gqlgen)` library.
101-
Their documentation contains lots of information on how to tweak your configuration + settings.

0 commit comments

Comments
 (0)