C++ example using our API
Our API uses GraphQL, below is an example of how to leverage GraphQL’s automatic code generation to work with our services as if it were part of your application itself.
-
Start a new project and install dependencies
Create project Setup
vcpkg
in the example#!/bin/bashmkdir example && cd example -
Setup
vcpkg
& install dependenciesCreate the
vcpkg.json
file:./vcpkg.json {"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:
Terminal window git submodule add https://github.com/microsoft/vcpkg./vcpkg/bootstrap-vcpkg.sh./vcpkg/vcpkg install -
Create a graphql file to query data
You choose what data you want to fetch
./queries/Materials.graphql query ListMaterials($page: Int, $pageSize: Int, $filters: [MaterialFilter!]) {materials(page: $page, pageSize: $pageSize, filters: $filters) {pagespageInfo {hasPreviousPagehasNextPage}objects {... on Material {idnamebrand {idname}}}}} -
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.Terminal window 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/include -
Create the
main.cpp
app entrypointAll 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.
./src/main.cpp #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 useboost
orlibcurl
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()));} -
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(ExampleAppPRIVATEcppgraphqlgen::graphqlservicecppgraphqlgen::graphqlclientcppgraphqlgen::graphqlresponsecppgraphqlgen::graphqlpegcppgraphqlgen::graphqlcorocppgraphqlgen::graphqljsontaocpp::pegtlcpr::cprBoost::json)target_include_directories(ExampleAppPUBLIC$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/generated>$<INSTALL_INTERFACE:generated/include>PRIVATE${VCPKG_DIR}/include)