31 Commits

Author SHA1 Message Date
Craig Silverstein e3227388fe Rename the query constant to have an underscore in it. (#241)
We got reports of conflicts with the old constant-name and symbols that
people were defining in their app.
2022-11-22 14:12:38 -08:00
Craig Silverstein 587f77046b Expose the graphql operation as a constant in the generated genqlient file (#238)
This allows client code to see the operation (query or mutation) exactly
as genqlient sends it over the wire. This data was already available in
the generated safelist.json file, but now it's easily available from Go
code as well.
    
Fixes #236

I have:
- [x] Written a clear PR title and description (above)
- [x] Signed the [Khan Academy CLA](https://www.khanacademy.org/r/cla)
- [x] Added tests covering my changes, if applicable
- [x] Included a link to the issue fixed, if applicable
- [x] Included documentation, for new features
- [x] Added an entry to the changelog
2022-11-21 08:35:09 -08:00
Jan-Hendrik Boll b2422452a1 Add GraphQL Extensions (#184)
This enables accessing the Extensions field, as defined in the response
format: https://spec.graphql.org/October2021/#sec-Response-Format

Extensions can be enabled using configuration option use_extensions.
This will change the return parameters of the generated client
functions. Making it a breaking change if enabled.

Since extensions are untyped as defined in the spec, the Client will
return an interface of type map[string]interface{}.
2022-03-30 13:48:01 -07:00
Ben Kraft 5995653583 Refactor argument-handling to use a struct (#103)
## Summary:
In this commit I refactor the argument-generation logic to move most of
the code out of the template and into the type-generator.  This logic
predates #51, and I didn't think to update it there, but I think it
benefits from similar treatment, for similar reasons.

Specifically, the main change is to treat variables as another struct
type we can generate, rather than handling them inline as a
`map[string]interface{}`.  Users still pass them the same way, but
instead of putting them into a `map[string]interface{}` and JSONifying
that, we generate a struct and put them there.

This turns out to simplify things quite a lot, because we already have a
lot of code to generate types.  Notably, the omitempty code goes from a
dozen lines to basically two, and fixes a bug (#43) in the process,
because now that we have a struct, `json.Marshal` will do our work for
us! (And, once we have syntax for it (#14), we'll be able to handle
field-level omitempty basically for free.)  More importantly, it will
simplify custom marshalers (#38, forthcoming) significantly, since we do
all that logic at the containing-struct level, but will need to apply it
to arguments.

It does require two breaking changes:

1. For folks implementing the `graphql.Client` API (rather than just
   calling `NewClient`): we now pass them variables as an `interface{}`
   rather than a `map[string]interface{}`.  For most callers, including
   Khan/webapp, this is basically a one-line change to the signature of
   their `MakeRequest`, and it should be a lot more future-proof.
2. genqlient's handling of the `omitempty` option has changed to match
   that of `encoding/json`, in particular it now never considers structs
   "empty".  The difference was never intentional (I just didn't realize
   that behavior of `encoding/json`); arguably our behavior was more
   useful but I think that's outweighed by the value of consistency with
   `encoding/json` as well as the simpler and more correct
   implementation (fixing #43 is actually quite nontrivial otherwise).
   Once we have custom unmarshaler support (#38), users will be able to
   map a zero value to JSON null if they wish, which is mostly if not
   entirely equivalent for GraphQL's purposes.

Issue: https://github.com/Khan/genqlient/issues/38
Issue: https://github.com/Khan/genqlient/issues/43

## Test plan:
make check

Author: benjaminjkraft

Reviewers: StevenACoffman, dnerdy, aberkan, jvoll, mahtabsabet, MiguelCastillo

Required Reviewers: 

Approved By: StevenACoffman, dnerdy

Checks:  Test (1.17),  Test (1.16),  Test (1.15),  Test (1.14),  Lint,  Lint,  Test (1.17),  Test (1.16),  Test (1.15),  Test (1.14)

Pull Request URL: https://github.com/Khan/genqlient/pull/103
2021-09-22 17:16:36 -07:00
Ben Kraft f72933fa0e Refactor import-loading to simplify the type-generation code (#101)
## Summary:
genqlient has some code (`imports.go`) dedicated to tracking which
imports we need and avoiding conflicts, as well as converting a
(restricted) Go expression like `map[string]github.com/me/mypkg.MyType`
to an import (`github.com/me/mypkg`) and a type-reference
(`map[string]mypkg.MyType`) to be used in the context of that import,
and at least making some attempt to track conflicts.  (Right now the
conflict-avoidance is not very smart, and not very well tested, but it
comes up rarely anyway.)  Sadly, that code was a bit cumbersome to use,
because you had to first register the imports (typically from
`convert.go`), then use them (often from the template).

In this commit I refactor the order we write things in order to allow a
significant simplification of how we import; in particular we no longer
have to guess in advance what imports which template will need; it can
just do `{{ref <expr>}}` as before, and it just works.  To do this, I:
- changed the importer to have only one API, which adds the import if
  needed, and returns the reference either way
- added a check that we don't add imports after they're written
- reorganized the toplevel templates a bit to make sure that check never
  fires; we now generate all the types and operations, then write the
  imports and glue it all together
This removes a bunch of silly code, and should simplify the process of
adding custom (un)marshalers (#38).

While I was at it, I put the documentation of what expressions we
support in a more visible place, and added a type-assertion that your
custom context type implements context.Context (if applicable).

## Test plan:
make check


Author: benjaminjkraft

Reviewers: StevenACoffman, dnerdy, aberkan, jvoll, mahtabsabet, MiguelCastillo

Required Reviewers: 

Approved By: StevenACoffman, dnerdy

Checks:  Test (1.17),  Test (1.16),  Test (1.15),  Test (1.14),  Lint,  Test (1.17),  Test (1.16),  Test (1.15),  Test (1.14),  Lint

Pull Request URL: https://github.com/Khan/genqlient/pull/101
2021-09-16 18:09:32 -07:00
Ben Kraft dc38360d9d Add a flag --init to write a default config (#81)
## Summary:
Steve pointed out (#73) that having genqlient with no arguments silently
use a default config file was a bit confusing, and changed it to use
`genqlient.yaml` by default (#74).  Mark pointed out (#76) that this
makes it a bit less convenient when you're starting from scratch; you
have to go create a config file.  In this commit I add a new init flag
that creates you a config file before using it.

Originally the suggestion was to use subcommands, e.g. we'd have
`genqlient init` and `genqlient generate` and so on.  But I couldn't
think of anything else we might want subcommands for in the future, and
it felt a little silly to make you type `generate` each time.  So
instead, I made it a flag, which has the nice property that you can do
`genqlient --init` and it will generate and then use a config file.  (I
mean, maybe it will immediately crash because you don't have a schema,
but hopefully that's still a useful clue as to what to do next!)  The
implmentation was fairly trivial.

Since we now have a nice way to generate a default config, I removed the
default values for most of the options; I've always felt they were
probably more confusing than helpful.  (And indeed, all the users I know
of (Khan/webapp, and the much smaller project Steve was working on, are
setting those options explicitly.)  This required a slight change to
the syntax to say "don't use context", which is probably also net clearer.

I decided this is also a good time to pull in a proper CLI parser (#31);
see ADR-504 for more on that choice.  This also adds some nice help
messages!

Fixes #76, #31.

Issue: https://github.com/Khan/genqlient/issues/76

## Test plan:
```
go run .
go run . --init
go run . --init example/genqlient.yaml     # refuses to clobber
go run . --init example/newgenqlient.yaml
```


Author: benjaminjkraft

Reviewers: dnerdy, aberkan, MiguelCastillo, StevenACoffman

Required Reviewers: 

Approved By: dnerdy

Checks:  Test (1.17),  Test (1.16),  Test (1.15),  Test (1.14),  Lint,  Test (1.17),  Test (1.16),  Test (1.15),  Test (1.14),  Lint

Pull Request URL: https://github.com/Khan/genqlient/pull/81
2021-09-10 15:49:54 -07:00
Ben Kraft 6c86eed770 Clean up, test, and document ContextType and ClientGetter options (#77)
## Summary:
ContextType is in use at Khan as a part of our ka-context system; it
basically just lets you configure the type to pass as the `ctx` argument
to genqlient helpers (or say to omit such an argument).  ClientGetter I
wrote thinking we might use it; then we didn't (because we have a few
different clients we may use) but it's not much code and may be helpful
to others.  In this commit I clean up, document, and add tests for both
options.

The cleanup is mainly for ClientGetter, which was kind of broken before
because it was a Go snippet but couldn't specify imports.  I was
thinking maybe you want to be able to write `ctx.Something()`, but I
just don't see how to make it work, so I made it a function of context,
which is probably the better idea anyway.

Additionally, I improved the documentation for both, and added tests for
those and several other config options that weren't completely tested.

Fixes #5.

Issue: https://github.com/Khan/genqlient/issues/5

## Test plan:
make check


Author: benjaminjkraft

Reviewers: dnerdy, aberkan, MiguelCastillo

Required Reviewers: 

Approved By: dnerdy

Checks:  Test (1.17),  Test (1.16),  Test (1.15),  Test (1.14),  Test (1.13),  Lint,  Test (1.17),  Test (1.16),  Test (1.15),  Test (1.14),  Test (1.13),  Lint

Pull Request URL: https://github.com/Khan/genqlient/pull/77
2021-09-07 09:58:49 -07:00
Ben Kraft c2e7dc4e5b Handle omitempty correctly for slices
We were generating broken code; fixes #43.  Also fixes a bug where
applying omitempty to the entire query was broken by e597cac74c.
2021-06-01 15:49:42 -07:00
Ben Kraft e597cac74c add option to force using a pointer 2021-04-12 16:01:21 -07:00
Ben Kraft 16523c1f81 add omitempty 2021-04-09 11:51:30 -07:00
Ben Kraft b4e8316c6a add support for custom scalars -- mainly adding proper import machinery 2021-04-08 13:07:31 -07:00
Ben Kraft 9fe8f09e8c more miscellaneous fixes while integrating into webapp 2021-04-01 15:04:36 -07:00
Ben Kraft cbebeaaed4 rename in code 2021-03-30 12:41:37 -07:00
Ben Kraft 2c52314494 set opname 2021-03-30 11:27:43 -07:00
Ben Kraft 937540d244 make client an interface 2021-03-25 14:08:12 -07:00
Ben Kraft dd85597577 more wiring for configurable context/client, theoretically should be good enough for khan use 2021-03-22 19:17:06 -07:00
Ben Kraft 59ca841a6b start of wiring for configurable context 2021-03-22 19:09:17 -07:00
Ben Kraft cf7136ca65 total rewrite to interface handling; not complete but it compiles 2020-07-16 13:28:43 -07:00
Ben Kraft 5042a9a549 allow omitting context 2020-05-01 18:45:39 -07:00
Ben Kraft b600df7877 big refactor to put the codegen onto methods of an object 2020-04-10 15:21:23 -07:00
Ben Kraft dfea9bf128 push type-name into types.go 2020-04-10 14:30:56 -07:00
Ben Kraft 01b903b053 Doc comments 2020-03-27 17:44:30 -07:00
Ben Kraft 9074926cea Set up a test 2020-03-27 15:57:22 -07:00
Ben Kraft 35699a73ef more README stuff, example README, other misc cleanup 2020-01-16 17:56:13 -08:00
Ben Kraft 7dfd03738c genql: bits of whitespace 2020-01-02 18:00:23 -08:00
Ben Kraft 9746c818fd genql: quick hack at variables 2020-01-02 17:52:55 -08:00
Ben Kraft 4d880a701e move a bunch of the logic from generated into client 2019-12-25 16:26:32 -05:00
Ben Kraft 9d4b5559f4 wire up example by way of testing 2019-12-24 16:05:10 -05:00
Ben Kraft e8b5ccbcda generates something mostly plausiblegit add . 2019-12-23 23:22:19 -05:00
Ben Kraft 7a20e2ae74 fill out the easy parts of the codegen 2019-12-23 21:07:07 -05:00
Ben Kraft efa9ccd122 add basic query struct, support 1.12 2019-12-23 19:35:38 -05:00