Skip to content

feat(sharedtypes): add clientgen --shared-types param to reuse types in schema #318

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 19 additions & 20 deletions include/RequestLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,30 +84,32 @@ struct [[nodiscard("unnecessary construction")]] RequestOptions
const std::string requestFilename;
const std::optional<std::string> operationName;
const bool noIntrospection = false;
const bool sharedTypes = false;
};

class SchemaLoader;

class [[nodiscard("unnecessary construction")]] RequestLoader
{
public:
explicit RequestLoader(RequestOptions && requestOptions, const SchemaLoader& schemaLoader);
explicit RequestLoader(RequestOptions&& requestOptions, const SchemaLoader& schemaLoader);

[[nodiscard("unnecessary call")]] std::string_view getRequestFilename() const noexcept;
[[nodiscard("unnecessary call")]] const OperationList& getOperations() const noexcept;
[[nodiscard("unnecessary call")]] std::string_view getOperationDisplayName(
const Operation& operation) const noexcept;
[[nodiscard("unnecessary call")]] std::string getOperationNamespace(const Operation& operation)
const noexcept;
[[nodiscard("unnecessary call")]] std::string_view getOperationType(const Operation& operation)
const noexcept;
[[nodiscard("unnecessary call")]] std::string getOperationNamespace(
const Operation& operation) const noexcept;
[[nodiscard("unnecessary call")]] std::string_view getOperationType(
const Operation& operation) const noexcept;
[[nodiscard("unnecessary call")]] std::string_view getRequestText() const noexcept;

[[nodiscard("unnecessary call")]] const ResponseType& getResponseType(
const Operation& operation) const noexcept;
[[nodiscard("unnecessary call")]] const RequestVariableList& getVariables(
const Operation& operation) const noexcept;

[[nodiscard("unnecessary call")]] bool useSharedTypes() const noexcept;
[[nodiscard("unnecessary call")]] const RequestInputTypeList& getReferencedInputTypes(
const Operation& operation) const noexcept;
[[nodiscard("unnecessary call")]] const RequestSchemaTypeList& getReferencedEnums(
Expand All @@ -116,32 +118,30 @@ class [[nodiscard("unnecessary construction")]] RequestLoader
[[nodiscard("unnecessary call")]] std::string getInputCppType(
const RequestSchemaType& wrappedInputType) const noexcept;
[[nodiscard("unnecessary call")]] std::string getInputCppType(
const RequestSchemaType& inputType,
const TypeModifierStack& modifiers) const noexcept;
const RequestSchemaType& inputType, const TypeModifierStack& modifiers) const noexcept;
[[nodiscard("unnecessary call")]] static std::string getOutputCppType(
std::string_view outputCppType,
const TypeModifierStack& modifiers) noexcept;
std::string_view outputCppType, const TypeModifierStack& modifiers) noexcept;

[[nodiscard("unnecessary call")]] static std::pair<RequestSchemaType, TypeModifierStack>
unwrapSchemaType(RequestSchemaType && type) noexcept;
unwrapSchemaType(RequestSchemaType&& type) noexcept;

private:
void buildSchema();
void addTypesToSchema();
[[nodiscard("unnecessary call")]] RequestSchemaType getSchemaType(std::string_view type,
const TypeModifierStack& modifiers) const noexcept;
[[nodiscard("unnecessary call")]] RequestSchemaType getSchemaType(
std::string_view type, const TypeModifierStack& modifiers) const noexcept;
void validateRequest() const;

[[nodiscard("unnecessary call")]] static std::string_view trimWhitespace(
std::string_view content) noexcept;

void findOperation();
void collectFragments() noexcept;
void collectVariables(Operation & operation) noexcept;
void collectInputTypes(Operation & operation, const RequestSchemaType& variableType) noexcept;
void reorderInputTypeDependencies(Operation & operation);
void collectEnums(Operation & operation, const RequestSchemaType& variableType) noexcept;
void collectEnums(Operation & operation, const ResponseField& responseField) noexcept;
void collectVariables(Operation& operation) noexcept;
void collectInputTypes(Operation& operation, const RequestSchemaType& variableType) noexcept;
void reorderInputTypeDependencies(Operation& operation);
void collectEnums(Operation& operation, const RequestSchemaType& variableType) noexcept;
void collectEnums(Operation& operation, const ResponseField& responseField) noexcept;

using FragmentDefinitionMap = std::map<std::string_view, const peg::ast_node*>;

Expand All @@ -150,8 +150,7 @@ class [[nodiscard("unnecessary construction")]] RequestLoader
{
public:
explicit SelectionVisitor(const SchemaLoader& schemaLoader,
const FragmentDefinitionMap& fragments,
const std::shared_ptr<schema::Schema>& schema,
const FragmentDefinitionMap& fragments, const std::shared_ptr<schema::Schema>& schema,
const RequestSchemaType& type);

void visit(const peg::ast_node& selection);
Expand All @@ -163,7 +162,7 @@ class [[nodiscard("unnecessary construction")]] RequestLoader
void visitFragmentSpread(const peg::ast_node& fragmentSpread);
void visitInlineFragment(const peg::ast_node& inlineFragment);

void mergeFragmentFields(ResponseFieldList && fragmentFields) noexcept;
void mergeFragmentFields(ResponseFieldList&& fragmentFields) noexcept;

const SchemaLoader& _schemaLoader;
const FragmentDefinitionMap& _fragments;
Expand Down
4 changes: 1 addition & 3 deletions samples/client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ add_subdirectory(subscribe)
add_subdirectory(nestedinput)
add_subdirectory(multiple)

add_subdirectory(benchmark)

if(GRAPHQL_BUILD_MODULES)
# client_benchmark
add_subdirectory(benchmark)
add_executable(client_benchmark benchmark.cpp)
target_link_libraries(client_benchmark PRIVATE
todaygraphql
benchmark_client)

if(WIN32 AND BUILD_SHARED_LIBS)
Expand Down
5 changes: 2 additions & 3 deletions samples/client/benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import GraphQL.Client;
import GraphQL.Service;

import GraphQL.Today.Mock;

import GraphQL.Benchmark.BenchmarkClient;
import GraphQL.Today.TodayClient;

using namespace graphql;

Expand Down Expand Up @@ -93,7 +92,7 @@ int main(int argc, char** argv)

try
{
using namespace client::query::Query;
using namespace today::client::query::Query;

auto query = GetRequestObject();
const auto& name = GetOperationName();
Expand Down
3 changes: 2 additions & 1 deletion samples/client/benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ cmake_minimum_required(VERSION 3.28)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/cppgraphqlgen-functions.cmake)

if(GRAPHQL_UPDATE_SAMPLES AND GRAPHQL_BUILD_CLIENTGEN)
update_graphql_client_files(benchmark ../../today/schema.today.graphql client.benchmark.today.graphql Benchmark benchmark)
update_graphql_client_files(benchmark ../../today/schema.today.graphql client.benchmark.today.graphql Today today --shared-types)
endif()

add_graphql_client_target(benchmark)
target_link_libraries(benchmark_client PRIVATE todaygraphql)
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

// WARNING! Do not edit this file manually, your changes will be overwritten.

#include "BenchmarkClient.h"
#include "TodayClient.h"

#include "graphqlservice/internal/SortedMap.h"

Expand All @@ -16,8 +16,9 @@

using namespace std::literals;

namespace graphql::client {
namespace benchmark {
namespace graphql {
namespace today {
namespace client {

const std::string& GetRequestText() noexcept
{
Expand Down Expand Up @@ -59,14 +60,16 @@ const peg::ast& GetRequestObject() noexcept
return s_request;
}

} // namespace benchmark
} // namespace client
} // namespace today
namespace client {

using namespace benchmark;
using namespace today;

template <>
query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo Response<query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo>::parse(response::Value&& response)
graphql::today::client::query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo Response<graphql::today::client::query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo>::parse(response::Value&& response)
{
query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo result;
graphql::today::client::query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo result;

if (response.type() == response::Type::Map)
{
Expand All @@ -86,9 +89,9 @@ query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo Re
}

template <>
query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment Response<query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment>::parse(response::Value&& response)
graphql::today::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment Response<graphql::today::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment>::parse(response::Value&& response)
{
query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment result;
graphql::today::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment result;

if (response.type() == response::Type::Map)
{
Expand Down Expand Up @@ -123,9 +126,9 @@ query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdg
}

template <>
query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge Response<query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge>::parse(response::Value&& response)
graphql::today::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge Response<graphql::today::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge>::parse(response::Value&& response)
{
query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge result;
graphql::today::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge result;

if (response.type() == response::Type::Map)
{
Expand All @@ -135,7 +138,7 @@ query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdg
{
if (member.first == R"js(node)js"sv)
{
result.node = ModifiedResponse<query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment>::parse<TypeModifier::Nullable>(std::move(member.second));
result.node = ModifiedResponse<graphql::today::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment>::parse<TypeModifier::Nullable>(std::move(member.second));
continue;
}
}
Expand All @@ -145,9 +148,9 @@ query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdg
}

template <>
query::Query::Response::appointments_AppointmentConnection Response<query::Query::Response::appointments_AppointmentConnection>::parse(response::Value&& response)
graphql::today::client::query::Query::Response::appointments_AppointmentConnection Response<graphql::today::client::query::Query::Response::appointments_AppointmentConnection>::parse(response::Value&& response)
{
query::Query::Response::appointments_AppointmentConnection result;
graphql::today::client::query::Query::Response::appointments_AppointmentConnection result;

if (response.type() == response::Type::Map)
{
Expand All @@ -157,12 +160,12 @@ query::Query::Response::appointments_AppointmentConnection Response<query::Query
{
if (member.first == R"js(pageInfo)js"sv)
{
result.pageInfo = ModifiedResponse<query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo>::parse(std::move(member.second));
result.pageInfo = ModifiedResponse<graphql::today::client::query::Query::Response::appointments_AppointmentConnection::pageInfo_PageInfo>::parse(std::move(member.second));
continue;
}
if (member.first == R"js(edges)js"sv)
{
result.edges = ModifiedResponse<query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge>::parse<TypeModifier::Nullable, TypeModifier::List, TypeModifier::Nullable>(std::move(member.second));
result.edges = ModifiedResponse<graphql::today::client::query::Query::Response::appointments_AppointmentConnection::edges_AppointmentEdge>::parse<TypeModifier::Nullable, TypeModifier::List, TypeModifier::Nullable>(std::move(member.second));
continue;
}
}
Expand All @@ -171,7 +174,9 @@ query::Query::Response::appointments_AppointmentConnection Response<query::Query
return result;
}

namespace query::Query {
} // namespace client

namespace today::client::query::Query {

const std::string& GetOperationName() noexcept
{
Expand All @@ -182,6 +187,8 @@ const std::string& GetOperationName() noexcept

Response parseResponse(response::Value&& response)
{
using namespace graphql::client;

Response result;

if (response.type() == response::Type::Map)
Expand All @@ -203,12 +210,12 @@ Response parseResponse(response::Value&& response)

[[nodiscard("unnecessary call")]] const std::string& Traits::GetRequestText() noexcept
{
return benchmark::GetRequestText();
return client::GetRequestText();
}

[[nodiscard("unnecessary call")]] const peg::ast& Traits::GetRequestObject() noexcept
{
return benchmark::GetRequestObject();
return client::GetRequestObject();
}

[[nodiscard("unnecessary call")]] const std::string& Traits::GetOperationName() noexcept
Expand All @@ -221,5 +228,5 @@ Response parseResponse(response::Value&& response)
return Query::parseResponse(std::move(response));
}

} // namespace query::Query
} // namespace graphql::client
} // namespace today::client::query::Query
} // namespace graphql
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@

#pragma once

#ifndef BENCHMARKCLIENT_H
#define BENCHMARKCLIENT_H
#ifndef TODAYCLIENT_H
#define TODAYCLIENT_H

#include "graphqlservice/GraphQLClient.h"
#include "graphqlservice/GraphQLParse.h"
#include "graphqlservice/GraphQLResponse.h"

#include "graphqlservice/internal/Version.h"

#include "TodaySchema.h"

#include <optional>
#include <string>
#include <vector>
Expand All @@ -22,12 +24,10 @@
static_assert(graphql::internal::MajorVersion == 5, "regenerate with clientgen: major version mismatch");
static_assert(graphql::internal::MinorVersion == 0, "regenerate with clientgen: minor version mismatch");

namespace graphql::client {
namespace graphql::today {

/// <summary>
/// Operation: query (unnamed)
/// </summary>
/// <code class="language-graphql">
/// # Operation: query (unnamed)
/// ```graphql
/// # Copyright (c) Microsoft Corporation. All rights reserved.
/// # Licensed under the MIT License.
///
Expand All @@ -46,21 +46,19 @@ namespace graphql::client {
/// }
/// }
/// }
/// </code>
namespace benchmark {
/// ```
namespace client {

// Return the original text of the request document.
[[nodiscard("unnecessary call")]] const std::string& GetRequestText() noexcept;

// Return a pre-parsed, pre-validated request object.
[[nodiscard("unnecessary call")]] const peg::ast& GetRequestObject() noexcept;

} // namespace benchmark

namespace query::Query {

using benchmark::GetRequestText;
using benchmark::GetRequestObject;
using graphql::today::client::GetRequestText;
using graphql::today::client::GetRequestObject;

// Return the name of this operation in the shared request document.
[[nodiscard("unnecessary call")]] const std::string& GetOperationName() noexcept;
Expand Down Expand Up @@ -108,6 +106,7 @@ struct Traits
};

} // namespace query::Query
} // namespace graphql::client
} // namespace client
} // namespace graphql::today

#endif // BENCHMARKCLIENT_H
#endif // TODAYCLIENT_H
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,21 @@

module;

#include "BenchmarkClient.h"
#include "TodayClient.h"

export module GraphQL.Benchmark.BenchmarkClient;
export module GraphQL.Today.TodayClient;

export namespace graphql::client {
export namespace graphql::today {

namespace benchmark {
namespace client {

using benchmark::GetRequestText;
using benchmark::GetRequestObject;

} // namespace benchmark
using client::GetRequestText;
using client::GetRequestObject;

namespace query::Query {

using benchmark::GetRequestText;
using benchmark::GetRequestObject;
using graphql::today::client::GetRequestText;
using graphql::today::client::GetRequestObject;
using Query::GetOperationName;

using Query::Response;
Expand All @@ -31,4 +29,5 @@ using Query::Traits;

} // namespace query::Query

} // namespace graphql::client
} // namespace client
} // namespace graphql::today
Loading