caffql
generates c++ types and GraphQL request and response serialization logic from a GraphQL json schema file.
-s, --schema arg input json schema file
-o, --output arg output generated header file
-n, --namespace arg generated namespace (default: caffql)
-a, --absl use absl optional and variant instead of std
-h, --help help
caffql \
--schema mygraphqlschema.json \
--output GeneratedCode.hpp
Make an introspection query to your graphql endpoint and use the resulting json response as the schema
parameter to caffql
.
caffql
generates a c++ header file with types necessary to perform queries.
- c++17 for
std::optional
andstd::variant
or c++11 and Abseil forabsl::optional
andabsl::variant
- nlohmann/json for request and response serialization
caffql
will generate request and response functions for each field of the input schema's operation types (query
, subscription
, and mutation
). Currently only a single field can be queried at once.
All subfields and nested types of that field will be included in the query, i.e. there is no way to query a subset of a model. The benefits to this approach are that you don't have to handwrite any queries and the generated request and response functions are kept simple, while the drawback is that you can't omit any unwanted data.
GraphQL Type | Generated C++ Type |
---|---|
Int | int32_t |
Float | double |
String | std::string |
ID | Id (std::string typealias) |
Boolean | bool |
Enum | enum class |
Object | struct |
Interface | struct containing std::variant of possible implementations |
Union | variant of possible types |
InputObject | struct |
List | std::vector |
Nullable fields | optional |
For forwards compatibility, a special Unknown
case is generated. Enum values that the client is unaware of will be deserialized to the Unknown
case.
Interfaces are generated as struct
s with an implementation
member that is a std::variant
of the possible implementations of the interface. For each field of the interface, a member function is generated that visits the implementation
and returns the field.
An alternative approach would be to use a pure abstract class for the interface and have the implementations inherit from it. However, that approach prevents using the interface type as a simple value type (which would require implementing something like a polymorphic value-copying smart pointer).
For forwards compatibility, a special Unknown<InterfaceName>
type is generated that contains the fields of the interface. Interface implementations that the client is unaware of will deserialize to the Unknown<InterfaceName>
type.
For forwards compatibility, the generated std::variant
adds std::monostate
as a possible type to handle unknown types that the client is unaware of.
- Go to CMake and download and install CMake tool for your version of MacOS.
- Launch CMake tool and in the
Where is the source code
input provide root of your CaffQL repo (i.e.~/workplace/CaffQL
) - In the
Where to build the binaries
input, specify the build output (i.e~/workplace/CaffQL/build
) - Click
Configure
button. Accept the prompt to createbuild
directory if it doesn't exist - Accept default options for the generator
Unix Makefiles
andUse default native compilers
. CMake will generate the list of parameters for your system configuration. - Click
Generate
. CMake tool will generate the list of files required for the build. - Go to
build
directory and runmake
$ cd build
$ make
- Look for the
build/caffql
executable being created - Copy
caffql
executable tousr/local/bin
[build] $ cp caffql /usr/local/bin
- Try running
caffql
[build] $ caffql --help
You should see the list of options of how to use the caffql tool.