Code Generation
Our API uses GraphQL, which enables automatic code generation to work with our services as if it were part of your application itself. Below are examples for different programming languages.
TypeScript Setup
Section titled “TypeScript Setup”1. Start a new project and install dependencies
Section titled “1. Start a new project and install dependencies”#!/bin/bashmkdir example && cd examplebun initbun add @graphql-codegen/cli @graphql-codegen/near-operation-file-preset --dev2. Setup codegen configuration
Section titled “2. Setup codegen configuration”We will create a codegen file with some configuration for how we want to generate the code.
import type { CodegenConfig } from "@graphql-codegen/cli";
const config: CodegenConfig = { overwrite: true, schema: "https://api.helioadditive.com/graphql" documents: "./**/*.graphql", generates: { "types.generated.ts": { plugins: ["typescript"], config: { useInterface: true, useTypeImports: false, declarationKind: { input: "interface", }, }, }, ".": { preset: "near-operation-file", presetConfig: { extension: ".generated.ts", baseTypesPath: "types.generated.ts", }, plugins: ["typescript-operations", "typed-document-node"], config: { useTypeImports: false, declarationKind: { input: "interface", }, }, }, },};
export default config;3. Create a graphql file to query data
Section titled “3. Create a graphql file to query data”You choose what data you want to fetch
query ListMaterials($page: Int, $pageSize: Int, $filters: [MaterialFilter!]) { materials(page: $page, pageSize: $pageSize, filters: $filters) { pages pageInfo { hasPreviousPage hasNextPage } objects { ... on Material { id name brand { id name } } } }}4. Autogenerate files
Section titled “4. Autogenerate files”Add a new script to your package.json to run the codegen tool.
{ "name": "example", "version": "0.1.0", "scripts": { ... "codegen": "graphql-codegen --config codegen.ts" },And then run it:
bun run codegen5. Utilize the generated code
Section titled “5. Utilize the generated code”import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client";import { MaterialsDocument } from "./queries/Materials.generated";
const apolloClient = new ApolloClient({ uri: "https://api.helioadditive.com/graphql", cache: new InMemoryCache(), link: new HttpLink({ uri: "https://api.helioadditive.com/graphql", headers: { "Content-Type": "application/json", Authorization: "Bearer <pat-token>" }, credentials: "include", fetchOptions: { cache: "no-store" }, }),});
const query = await apolloClient.query({ query: MaterialsDocument, variables: { pageSize: 20, page: 1 }, fetchPolicy: "no-cache", }); for (const material of materials.data.materials.objects) { console.log(`Material ID: ${material.id}, Name: ${material.name}`); }Python Setup
Section titled “Python Setup”1. Start a new project and install dependencies
Section titled “1. Start a new project and install dependencies”uv is a modern Python package manager:
#!/bin/bashmkdir example && cd exampleuv inituv add ariadne-codegen # GraphQL codegen tool2. Setup codegen configuration
Section titled “2. Setup codegen configuration”Update the pyproject.toml file to specify settings for autogenerated code.
[project]name = "example"version = "0.1.0"description = "Add your description here"readme = "README.md"requires-python = ">=3.13"dependencies = [ "ariadne-codegen>=0.14.0",]
[tool.ariadne-codegen] target_package_path = "./client" queries_path = "./queries" remote_schema_url = "https://api.helioadditive.com/graphql" target_package_name = "graphql_client" async_client = true include_comments = "stable" convert_to_snake_case = true include_all_inputs = true include_all_emums = true3. Create a graphql file to query data
Section titled “3. Create a graphql file to query data”You choose what data you want to receive
query ListMaterials($page: Int, $pageSize: Int, $filters: [MaterialFilter!]) { materials(page: $page, pageSize: $pageSize, filters: $filters) { pages pageInfo { hasPreviousPage hasNextPage } objects { ... on Material { id name brand { id name } } } }}4. Autogenerate the code
Section titled “4. Autogenerate the code”uv run ariadne-codegen --config pyproject.tomlAll generated code should now be generated in the ./client directory
5. Update the main.py to use the generated code
Section titled “5. Update the main.py to use the generated code”Notice that there is no logic to handle the requests, that logic is already autogeneratd and baked into functions like materials
import asyncioimport httpxfrom client.client import client
headers = {"Authorization": "Bearer <helio_pat>"}graphql_client = Client( url="https://api.helioadditive.com/graphql", headers=headers, http_client=httpx.AsyncClient(headers=headers, timeout=60))
async def main(): materials = await graphql_client.materials(page_size=20) for material in materials.objects: # The `material` object is fully type inferred material_id = material.id material_name = material.name
if __name__ == "__main__": asyncio.run(main())6. Next steps
Section titled “6. Next steps”You can now add any .graphql files you need into the queries directory, re-run the codegen tool, and start using it directly in the code.
C++ Setup
Section titled “C++ Setup”1. Start a new project and install dependencies
Section titled “1. Start a new project and install dependencies”Create project Setup vcpkg in the example
#!/bin/bashmkdir example && cd example2. Setup vcpkg & install dependencies
Section titled “2. Setup vcpkg & install dependencies”Create the vcpkg.json file:
{ "name": "example", "version-string": "0.0.1", "builtin-baseline": "095a29ce59608465032c3747307dd0009b3e089c", "dependencies": [ { "name": "pegtl", "version>=": "3.2.8" }, { "name": "cppgraphqlgen", "version>=": "4.5.7", "features": ["clientgen", "rapidjson"] }, { "name": "boost-json", "version>=": "1.88.0" }, { "name": "cpr", "version>=": "1.11.2" } ]}And then setup / install:
git submodule add https://github.com/microsoft/vcpkg./vcpkg/bootstrap-vcpkg.sh./vcpkg/vcpkg install3. Create a graphql file to query data
Section titled “3. Create a graphql file to query data”You choose what data you want to fetch
query ListMaterials($page: Int, $pageSize: Int, $filters: [MaterialFilter!]) { materials(page: $page, pageSize: $pageSize, filters: $filters) { pages pageInfo { hasPreviousPage hasNextPage } objects { ... on Material { id name brand { id name } } } }}4. Autogenerate the code
Section titled “4. Autogenerate the code”clientgen allows us to autogenerated all of the functions, structs and enums needed to handle
our query files. This means we don’t need to write any manual requests with possible incorrect types, just call the function as if it were part of the library itself.
mkdir -p ./generated/srcmkdir -p ./generated/includecurl https://api.helioadditive.com/graphql/scehma -o schema.graphqls./vcpkg/packages/cppgraphqlgen_arm64-osx/tools/cppgraphqlgen/clientgen \ --schema ./schema.graphqls \ --request queries/Materials.graphql \ --namespace HelioAdditive \ --prefix Materials \ --source-dir ./generated/src \ --header-dir ./generated/include5. Create the main.cpp app entrypoint
Section titled “5. Create the main.cpp app entrypoint”All of the structs, enums and functions to handle all types to/from our API are already autogenerated including the serialization logic. This means you can now write interact with our API with 100% type confidence.
#include <iostream>#include <string>
#include "MaterialsClient.h"#include "graphqlservice/GraphQLResponse.h"#include "graphqlservice/JSONResponse.h"
namespace Materials = graphql::client::query::Materials;
int main() { const std::string query = Materials::GetRequestText(); graphql::response::Value variables = Materials::serializeVariables(Materials::Variables{.pageSize = 20, .page = 1}); auto parsed_response = Materials::parseResponse(sendHttpRequest(query, variables));
for (const auto &material : parsed_response.materials.objects) { std::cout << "Material ID: " << material.id.c_str() << ", Name: " << material.name << '\n'; }
return 0;}NOTE: C++ autogenerated GraphQL code does not include logic to handle the HTTP requests like in other languages, as such an example function of how to handle the HTTP requests is shown below with cpr, but one could easily use boost or libcurl based on what is used in your project:
#include <cpr/cpr.h>#include <boost/json.hpp>
graphql::response::Value sendHttpRequest(const std::string &query, graphql::response::Value &variables) { std::string body = boost::json::serialize(boost::json::object{ {"query", query}, {"variables", boost::json::parse(graphql::response::toJSON(std::move(variables))).as_object()} }); return graphql::response::parseJSON(boost::json::serialize(boost::json::parse( cpr::Post( cpr::Url{"https://api.helioadditive.com/graphql"}, cpr::Header{{"Content-Type", "application/json"}, {"Authorization", "Bearer <pat_token>"}}, cpr::Body{body} ).text ).as_object()["data"].as_object()));}6. Build
Section titled “6. Build”C++ is an advanced language and every build system is different. For below example shows how one could use CMake to build:
cmake_minimum_required(VERSION 3.14)project(ExampleApp)set(CMAKE_CXX_STANDARD 20)set(CMAKE_CXX_FLAGS "-std=c++20 -O3 ")
include_directories(${VCPKG_DIR}/include)link_directories(${VCPKG_DIR}/lib)
FIND_PACKAGE(CURL)find_package(Boost REQUIRED COMPONENTS json)find_package(cppgraphqlgen 4.5.7 CONFIG REQUIRED)find_package(cpr 1.11.1 REQUIRED)
include_directories(generated/include)file(GLOB_RECURSE GENERATED_SRC "generated/src/*.cpp")file(GLOB_RECURSE GENERATED_HEADERS "generated/include/*.h")
add_executable(ExampleApp src/main.cpp ${GENERATED_SRC})include_directories({CURL_INCLUDE_DIRS})target_link_libraries(ExampleApp PRIVATE cppgraphqlgen::graphqlservice cppgraphqlgen::graphqlclient cppgraphqlgen::graphqlresponse cppgraphqlgen::graphqlpeg cppgraphqlgen::graphqlcoro cppgraphqlgen::graphqljson taocpp::pegtl cpr::cpr Boost::json)target_include_directories(ExampleApp PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/generated> $<INSTALL_INTERFACE:generated/include> PRIVATE ${VCPKG_DIR}/include)