Skip to content
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

fix: #323 #327

Merged
merged 6 commits into from
Oct 21, 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
8 changes: 8 additions & 0 deletions include/graphqlservice/GraphQLService.h
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,9 @@ class [[nodiscard("unnecessary construction")]] Object : public std::enable_shar
GRAPHQLSERVICE_EXPORT explicit Object(TypeNames&& typeNames, ResolverMap&& resolvers) noexcept;
GRAPHQLSERVICE_EXPORT virtual ~Object() = default;

[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::shared_ptr<Object> StitchObject(
const std::shared_ptr<const Object>& added) const;

[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT AwaitableResolver resolve(
const SelectionSetParams& selectionSetParams, const peg::ast_node& selection,
const FragmentMap& fragments, const response::Value& variables) const;
Expand All @@ -846,6 +849,7 @@ class [[nodiscard("unnecessary construction")]] Object : public std::enable_shar
private:
TypeNames _typeNames;
ResolverMap _resolvers;
std::vector<std::shared_ptr<const Object>> _stitched;
};

// Test if this Type inherits from Object.
Expand Down Expand Up @@ -1440,6 +1444,9 @@ class [[nodiscard("unnecessary construction")]] Request
GRAPHQLSERVICE_EXPORT virtual ~Request();

public:
[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::shared_ptr<const Request> stitch(
const std::shared_ptr<const Request>& added) const;

[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::list<schema_error> validate(
peg::ast& query) const;

Expand All @@ -1466,6 +1473,7 @@ class [[nodiscard("unnecessary construction")]] Request
collectRegistrations(std::string_view field, RequestDeliverFilter&& filter) const noexcept;

const TypeMap _operations;
const std::shared_ptr<schema::Schema> _schema;
mutable std::mutex _validationMutex {};
const std::unique_ptr<ValidateExecutableVisitor> _validation;
mutable std::mutex _subscriptionMutex {};
Expand Down
6 changes: 6 additions & 0 deletions include/graphqlservice/internal/Schema.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class [[nodiscard("unnecessary construction")]] Schema : public std::enable_shar
GRAPHQLSERVICE_EXPORT explicit Schema(
bool noIntrospection = false, std::string_view description = "");

[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::shared_ptr<Schema> StitchSchema(
const std::shared_ptr<const Schema>& added) const;

GRAPHQLSERVICE_EXPORT void AddQueryType(std::shared_ptr<ObjectType> query);
GRAPHQLSERVICE_EXPORT void AddMutationType(std::shared_ptr<ObjectType> mutation);
GRAPHQLSERVICE_EXPORT void AddSubscriptionType(std::shared_ptr<ObjectType> subscription);
Expand Down Expand Up @@ -74,6 +77,9 @@ class [[nodiscard("unnecessary construction")]] Schema : public std::enable_shar
directives() const noexcept;

private:
[[nodiscard("unnecessary call")]] std::shared_ptr<const BaseType> StitchFieldType(
std::shared_ptr<const BaseType> fieldType);

const bool _noIntrospection = false;
const std::string_view _description;

Expand Down
5 changes: 5 additions & 0 deletions samples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ endif()

add_subdirectory(client)
add_subdirectory(learn)

if(GRAPHQL_BUILD_MODULES)
add_subdirectory(stitched)
endif()

add_subdirectory(validation)

if(GRAPHQL_BUILD_HTTP_SAMPLE)
Expand Down
22 changes: 14 additions & 8 deletions samples/learn/StarWarsData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ using namespace std::literals;

namespace graphql::star_wars {

std::shared_ptr<service::Request> GetService() noexcept
std::shared_ptr<learn::object::Query> MakeQuery() noexcept
{
auto luke = std::make_shared<learn::Human>("1000"s,
std::make_optional("Luke Skywalker"s),
Expand Down Expand Up @@ -111,14 +111,20 @@ std::shared_ptr<service::Request> GetService() noexcept
{ artoo->getId(), artoo },
};

auto query =
std::make_shared<learn::Query>(std::move(heroes), std::move(humans), std::move(droids));
auto mutation = std::make_shared<learn::Mutation>();
auto service = std::make_shared<learn::Operations>(std::move(query),
std::move(mutation),
std::shared_ptr<learn::Subscription> {});
return std::make_shared<learn::object::Query>(
std::make_shared<learn::Query>(std::move(heroes), std::move(humans), std::move(droids)));
}

return service;
std::shared_ptr<learn::object::Mutation> MakeMutation() noexcept
{
return std::make_shared<learn::object::Mutation>(std::make_shared<learn::Mutation>());
}

std::shared_ptr<service::Request> GetService() noexcept
{
return std::make_shared<learn::Operations>(MakeQuery(),
MakeMutation(),
std::shared_ptr<learn::object::Subscription> {});
}

} // namespace graphql::star_wars
34 changes: 34 additions & 0 deletions samples/stitched/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

cmake_minimum_required(VERSION 3.28)

add_library(stitchedschema STATIC
StitchedSchema.cpp)
target_link_libraries(stitchedschema PUBLIC star_wars todaygraphql)
target_include_directories(stitchedschema INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

add_executable(stitched sample.cpp)
target_link_libraries(stitched PRIVATE
stitchedschema
graphqljson)

if(WIN32 AND BUILD_SHARED_LIBS)
add_custom_command(OUTPUT copied_sample_dlls
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:graphqlservice>
$<TARGET_FILE:graphqljson>
$<TARGET_FILE:graphqlpeg>
$<TARGET_FILE:graphqlresponse>
${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E touch copied_sample_dlls
DEPENDS
graphqlservice
graphqljson
graphqlpeg
graphqlresponse)

add_custom_target(copy_stitched_sample_dlls DEPENDS copied_sample_dlls)

add_dependencies(stitched copy_stitched_sample_dlls)
endif()
18 changes: 18 additions & 0 deletions samples/stitched/StitchedSchema.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "StitchedSchema.h"

#include "StarWarsData.h"
#include "StarWarsSchema.h"

import GraphQL.Today.Mock;

namespace graphql::stitched {

std::shared_ptr<const service::Request> GetService()
{
return star_wars::GetService()->stitch(today::mock_service()->service);
}

} // namespace graphql::stitched
20 changes: 20 additions & 0 deletions samples/stitched/StitchedSchema.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#pragma once

#ifndef STITCHEDSCHEMA_H
#define STITCHEDSCHEMA_H

#include "graphqlservice/GraphQLService.h"

#include "StarWarsSharedTypes.h"
#include "TodaySharedTypes.h"

namespace graphql::stitched {

std::shared_ptr<const service::Request> GetService();

} // namespace graphql::stitched

#endif // STITCHEDSCHEMA_H
57 changes: 57 additions & 0 deletions samples/stitched/sample.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "StitchedSchema.h"

#include "graphqlservice/JSONResponse.h"

#include <cstdio>
#include <iostream>
#include <iterator>
#include <stdexcept>

using namespace graphql;

int main(int argc, char** argv)
{
auto service = stitched::GetService();

std::cout << "Created the service..." << std::endl;

try
{
peg::ast query;

if (argc > 1)
{
query = peg::parseFile(argv[1]);
}
else
{
std::istream_iterator<char> start { std::cin >> std::noskipws }, end {};
std::string input { start, end };

query = peg::parseString(std::move(input));
}

if (!query.root)
{
std::cerr << "Unknown error!" << std::endl;
std::cerr << std::endl;
return 1;
}

std::cout << "Executing query..." << std::endl;

std::cout << response::toJSON(
service->resolve({ query, ((argc > 2) ? argv[2] : "") }).get())
<< std::endl;
}
catch (const std::runtime_error& ex)
{
std::cerr << ex.what() << std::endl;
return 1;
}

return 0;
}
49 changes: 34 additions & 15 deletions samples/today/TodayMock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,47 +62,66 @@ const response::IdType& getFakeFolderId() noexcept
return s_fakeId;
}

std::unique_ptr<TodayMockService> mock_service() noexcept
std::shared_ptr<Query> mock_query(const std::shared_ptr<TodayMockService>& service) noexcept
{
auto result = std::make_unique<TodayMockService>();

auto query = std::make_shared<Query>(
[mockService = result.get()]() -> std::vector<std::shared_ptr<Appointment>> {
++mockService->getAppointmentsCount;
return std::make_shared<Query>(
[weakService = std::weak_ptr { service }]() -> std::vector<std::shared_ptr<Appointment>> {
if (auto mockService = weakService.lock())
{
++mockService->getAppointmentsCount;
}
return { std::make_shared<Appointment>(response::IdType(getFakeAppointmentId()),
"tomorrow",
"Lunch?",
false) };
},
[mockService = result.get()]() -> std::vector<std::shared_ptr<Task>> {
++mockService->getTasksCount;
[weakService = std::weak_ptr { service }]() -> std::vector<std::shared_ptr<Task>> {
if (auto mockService = weakService.lock())
{
++mockService->getTasksCount;
}
return {
std::make_shared<Task>(response::IdType(getFakeTaskId()), "Don't forget", true)
};
},
[mockService = result.get()]() -> std::vector<std::shared_ptr<Folder>> {
++mockService->getUnreadCountsCount;
[weakService = std::weak_ptr { service }]() -> std::vector<std::shared_ptr<Folder>> {
if (auto mockService = weakService.lock())
{
++mockService->getUnreadCountsCount;
}
return {
std::make_shared<Folder>(response::IdType(getFakeFolderId()), "\"Fake\" Inbox", 3)
};
});
auto mutation = std::make_shared<Mutation>(
}

std::shared_ptr<Mutation> mock_mutation() noexcept
{
return std::make_shared<Mutation>(
[](CompleteTaskInput&& input) -> std::shared_ptr<CompleteTaskPayload> {
return std::make_shared<CompleteTaskPayload>(
std::make_shared<Task>(std::move(input.id), "Mutated Task!", *(input.isComplete)),
std::move(input.clientMutationId));
});
auto subscription = std::make_shared<NextAppointmentChange>(
}

std::shared_ptr<NextAppointmentChange> mock_subscription() noexcept
{
return std::make_shared<NextAppointmentChange>(
[](const std::shared_ptr<service::RequestState>&) -> std::shared_ptr<Appointment> {
return { std::make_shared<Appointment>(response::IdType(getFakeAppointmentId()),
"tomorrow",
"Lunch?",
true) };
});
}

std::shared_ptr<TodayMockService> mock_service() noexcept
{
auto result = std::make_shared<TodayMockService>();

result->service = std::make_shared<Operations>(std::move(query),
std::move(mutation),
std::move(subscription));
result->service =
std::make_shared<Operations>(mock_query(result), mock_mutation(), mock_subscription());

return result;
}
Expand Down
2 changes: 1 addition & 1 deletion samples/today/TodayMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct TodayMockService
std::size_t getUnreadCountsCount {};
};

std::unique_ptr<TodayMockService> mock_service() noexcept;
std::shared_ptr<TodayMockService> mock_service() noexcept;

struct RequestState : service::RequestState
{
Expand Down
Loading