API GraphQL com C++: tutorial passo a passo
GraphQL é uma linguagem de consulta para APIs, desenvolvida pelo Facebook. Diferente do REST, ele permite que o cliente solicite apenas os dados de que precisa, reduzindo o volume de informações transmitidas e acelerando a operação dos aplicativos. Neste tutorial, criaremos um servidor GraphQL simples em C++ usando a biblioteca graphql-cpp. Você aprenderá como definir o schema, escrever resolvers e processar queries e mutations.
O que é GraphQL e por que C++?
GraphQL fornece um único endpoint para todas as consultas. Os conceitos principais são:
- Schema — descrição dos tipos de dados e operações disponíveis (queries, mutations, subscriptions).
- Queries — operações de leitura de dados.
- Mutations — operações de escrita/alteração de dados.
- Resolvers — funções que retornam dados para cada campo.
C++ é uma linguagem poderosa para sistemas de alta carga. Usar GraphQL com C++ permite criar APIs eficientes e escaláveis. A biblioteca graphql-cpp fornece uma interface conveniente para integração.
Instalação e configuração do projeto
Para trabalhar, precisaremos de:
- Compilador C++17 (por exemplo, g++ ou MSVC).
- Biblioteca
graphql-cpp(instalação via vcpkg ou compilação a partir do código-fonte). - Servidor HTTP (usaremos
cpp-httplibpara simplicidade).
Instalação via vcpkg
vcpkg install graphql-cppvcpkg install cpp-httplibEstrutura do projeto
Crie os arquivos:
main.cpp— ponto de entrada e servidor HTTP.schema.hpp— definição do schema GraphQL.resolvers.hpp— implementação dos resolvers.CMakeLists.txt— configuração da compilação.
Definição do schema GraphQL
Criaremos um schema simples para gerenciar uma lista de usuários. O tipo User contém os campos id, name e email. Queries: users (lista de todos os usuários) e user(id: ID!) (um usuário). Mutation: addUser(name: String!, email: String!): User.
No arquivo schema.hpp:
#ifndef SCHEMA_HPP#define SCHEMA_HPP
#include <graphqlcpp/GraphQLSchema.h>
using namespace graphqlcpp;
// Define o tipo Userauto userType = std::make_shared<ObjectType>( "User", { {"id", Type::NonNull(Type::ID)}, {"name", Type::NonNull(Type::String)}, {"email", Type::NonNull(Type::String)} });
// Define o Queryauto queryType = std::make_shared<ObjectType>( "Query", { {"users", Type::List(Type::NonNull(userType))}, {"user", Type::NonNull(userType), {{"id", Type::NonNull(Type::ID)}}} });
// Define o Mutationauto mutationType = std::make_shared<ObjectType>( "Mutation", { {"addUser", Type::NonNull(userType), { {"name", Type::NonNull(Type::String)}, {"email", Type::NonNull(Type::String)} }} });
// Monta o schemaauto schema = std::make_shared<Schema>(queryType, mutationType);
#endif // SCHEMA_HPPImplementação dos resolvers
Resolvers são funções que retornam dados para cada campo. No nosso exemplo, os dados serão armazenados em um vetor global. No arquivo resolvers.hpp:
#ifndef RESOLVERS_HPP#define RESOLVERS_HPP
#include <vector>#include <string>#include <graphqlcpp/Resolvers.h>
using namespace graphqlcpp;
struct User { std::string id; std::string name; std::string email;};
std::vector<User> users = { {"1",