Skip to content

Commit e85fc7e

Browse files
authored
Merge pull request microsoft#327 from wravery/schema-stitch
fix: microsoft#323
2 parents a610521 + 8b0102c commit e85fc7e

16 files changed

+909
-28
lines changed

include/graphqlservice/GraphQLService.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,9 @@ class [[nodiscard("unnecessary construction")]] Object : public std::enable_shar
824824
GRAPHQLSERVICE_EXPORT explicit Object(TypeNames&& typeNames, ResolverMap&& resolvers) noexcept;
825825
GRAPHQLSERVICE_EXPORT virtual ~Object() = default;
826826

827+
[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::shared_ptr<Object> StitchObject(
828+
const std::shared_ptr<const Object>& added) const;
829+
827830
[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT AwaitableResolver resolve(
828831
const SelectionSetParams& selectionSetParams, const peg::ast_node& selection,
829832
const FragmentMap& fragments, const response::Value& variables) const;
@@ -846,6 +849,7 @@ class [[nodiscard("unnecessary construction")]] Object : public std::enable_shar
846849
private:
847850
TypeNames _typeNames;
848851
ResolverMap _resolvers;
852+
std::vector<std::shared_ptr<const Object>> _stitched;
849853
};
850854

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

14421446
public:
1447+
[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::shared_ptr<const Request> stitch(
1448+
const std::shared_ptr<const Request>& added) const;
1449+
14431450
[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::list<schema_error> validate(
14441451
peg::ast& query) const;
14451452

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

14681475
const TypeMap _operations;
1476+
const std::shared_ptr<schema::Schema> _schema;
14691477
mutable std::mutex _validationMutex {};
14701478
const std::unique_ptr<ValidateExecutableVisitor> _validation;
14711479
mutable std::mutex _subscriptionMutex {};

include/graphqlservice/internal/Schema.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class [[nodiscard("unnecessary construction")]] Schema : public std::enable_shar
4545
GRAPHQLSERVICE_EXPORT explicit Schema(
4646
bool noIntrospection = false, std::string_view description = "");
4747

48+
[[nodiscard("unnecessary call")]] GRAPHQLSERVICE_EXPORT std::shared_ptr<Schema> StitchSchema(
49+
const std::shared_ptr<const Schema>& added) const;
50+
4851
GRAPHQLSERVICE_EXPORT void AddQueryType(std::shared_ptr<ObjectType> query);
4952
GRAPHQLSERVICE_EXPORT void AddMutationType(std::shared_ptr<ObjectType> mutation);
5053
GRAPHQLSERVICE_EXPORT void AddSubscriptionType(std::shared_ptr<ObjectType> subscription);
@@ -74,6 +77,9 @@ class [[nodiscard("unnecessary construction")]] Schema : public std::enable_shar
7477
directives() const noexcept;
7578

7679
private:
80+
[[nodiscard("unnecessary call")]] std::shared_ptr<const BaseType> StitchFieldType(
81+
std::shared_ptr<const BaseType> fieldType);
82+
7783
const bool _noIntrospection = false;
7884
const std::string_view _description;
7985

samples/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ endif()
99

1010
add_subdirectory(client)
1111
add_subdirectory(learn)
12+
13+
if(GRAPHQL_BUILD_MODULES)
14+
add_subdirectory(stitched)
15+
endif()
16+
1217
add_subdirectory(validation)
1318

1419
if(GRAPHQL_BUILD_HTTP_SAMPLE)

samples/learn/StarWarsData.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ using namespace std::literals;
1414

1515
namespace graphql::star_wars {
1616

17-
std::shared_ptr<service::Request> GetService() noexcept
17+
std::shared_ptr<learn::object::Query> MakeQuery() noexcept
1818
{
1919
auto luke = std::make_shared<learn::Human>("1000"s,
2020
std::make_optional("Luke Skywalker"s),
@@ -111,14 +111,20 @@ std::shared_ptr<service::Request> GetService() noexcept
111111
{ artoo->getId(), artoo },
112112
};
113113

114-
auto query =
115-
std::make_shared<learn::Query>(std::move(heroes), std::move(humans), std::move(droids));
116-
auto mutation = std::make_shared<learn::Mutation>();
117-
auto service = std::make_shared<learn::Operations>(std::move(query),
118-
std::move(mutation),
119-
std::shared_ptr<learn::Subscription> {});
114+
return std::make_shared<learn::object::Query>(
115+
std::make_shared<learn::Query>(std::move(heroes), std::move(humans), std::move(droids)));
116+
}
120117

121-
return service;
118+
std::shared_ptr<learn::object::Mutation> MakeMutation() noexcept
119+
{
120+
return std::make_shared<learn::object::Mutation>(std::make_shared<learn::Mutation>());
121+
}
122+
123+
std::shared_ptr<service::Request> GetService() noexcept
124+
{
125+
return std::make_shared<learn::Operations>(MakeQuery(),
126+
MakeMutation(),
127+
std::shared_ptr<learn::object::Subscription> {});
122128
}
123129

124130
} // namespace graphql::star_wars

samples/stitched/CMakeLists.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
cmake_minimum_required(VERSION 3.28)
5+
6+
add_library(stitchedschema STATIC
7+
StitchedSchema.cpp)
8+
target_link_libraries(stitchedschema PUBLIC star_wars todaygraphql)
9+
target_include_directories(stitchedschema INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
10+
11+
add_executable(stitched sample.cpp)
12+
target_link_libraries(stitched PRIVATE
13+
stitchedschema
14+
graphqljson)
15+
16+
if(WIN32 AND BUILD_SHARED_LIBS)
17+
add_custom_command(OUTPUT copied_sample_dlls
18+
COMMAND ${CMAKE_COMMAND} -E copy_if_different
19+
$<TARGET_FILE:graphqlservice>
20+
$<TARGET_FILE:graphqljson>
21+
$<TARGET_FILE:graphqlpeg>
22+
$<TARGET_FILE:graphqlresponse>
23+
${CMAKE_CURRENT_BINARY_DIR}
24+
COMMAND ${CMAKE_COMMAND} -E touch copied_sample_dlls
25+
DEPENDS
26+
graphqlservice
27+
graphqljson
28+
graphqlpeg
29+
graphqlresponse)
30+
31+
add_custom_target(copy_stitched_sample_dlls DEPENDS copied_sample_dlls)
32+
33+
add_dependencies(stitched copy_stitched_sample_dlls)
34+
endif()

samples/stitched/StitchedSchema.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#include "StitchedSchema.h"
5+
6+
#include "StarWarsData.h"
7+
#include "StarWarsSchema.h"
8+
9+
import GraphQL.Today.Mock;
10+
11+
namespace graphql::stitched {
12+
13+
std::shared_ptr<const service::Request> GetService()
14+
{
15+
return star_wars::GetService()->stitch(today::mock_service()->service);
16+
}
17+
18+
} // namespace graphql::stitched

samples/stitched/StitchedSchema.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#pragma once
5+
6+
#ifndef STITCHEDSCHEMA_H
7+
#define STITCHEDSCHEMA_H
8+
9+
#include "graphqlservice/GraphQLService.h"
10+
11+
#include "StarWarsSharedTypes.h"
12+
#include "TodaySharedTypes.h"
13+
14+
namespace graphql::stitched {
15+
16+
std::shared_ptr<const service::Request> GetService();
17+
18+
} // namespace graphql::stitched
19+
20+
#endif // STITCHEDSCHEMA_H

samples/stitched/sample.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#include "StitchedSchema.h"
5+
6+
#include "graphqlservice/JSONResponse.h"
7+
8+
#include <cstdio>
9+
#include <iostream>
10+
#include <iterator>
11+
#include <stdexcept>
12+
13+
using namespace graphql;
14+
15+
int main(int argc, char** argv)
16+
{
17+
auto service = stitched::GetService();
18+
19+
std::cout << "Created the service..." << std::endl;
20+
21+
try
22+
{
23+
peg::ast query;
24+
25+
if (argc > 1)
26+
{
27+
query = peg::parseFile(argv[1]);
28+
}
29+
else
30+
{
31+
std::istream_iterator<char> start { std::cin >> std::noskipws }, end {};
32+
std::string input { start, end };
33+
34+
query = peg::parseString(std::move(input));
35+
}
36+
37+
if (!query.root)
38+
{
39+
std::cerr << "Unknown error!" << std::endl;
40+
std::cerr << std::endl;
41+
return 1;
42+
}
43+
44+
std::cout << "Executing query..." << std::endl;
45+
46+
std::cout << response::toJSON(
47+
service->resolve({ query, ((argc > 2) ? argv[2] : "") }).get())
48+
<< std::endl;
49+
}
50+
catch (const std::runtime_error& ex)
51+
{
52+
std::cerr << ex.what() << std::endl;
53+
return 1;
54+
}
55+
56+
return 0;
57+
}

samples/today/TodayMock.cpp

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,47 +62,66 @@ const response::IdType& getFakeFolderId() noexcept
6262
return s_fakeId;
6363
}
6464

65-
std::unique_ptr<TodayMockService> mock_service() noexcept
65+
std::shared_ptr<Query> mock_query(const std::shared_ptr<TodayMockService>& service) noexcept
6666
{
67-
auto result = std::make_unique<TodayMockService>();
68-
69-
auto query = std::make_shared<Query>(
70-
[mockService = result.get()]() -> std::vector<std::shared_ptr<Appointment>> {
71-
++mockService->getAppointmentsCount;
67+
return std::make_shared<Query>(
68+
[weakService = std::weak_ptr { service }]() -> std::vector<std::shared_ptr<Appointment>> {
69+
if (auto mockService = weakService.lock())
70+
{
71+
++mockService->getAppointmentsCount;
72+
}
7273
return { std::make_shared<Appointment>(response::IdType(getFakeAppointmentId()),
7374
"tomorrow",
7475
"Lunch?",
7576
false) };
7677
},
77-
[mockService = result.get()]() -> std::vector<std::shared_ptr<Task>> {
78-
++mockService->getTasksCount;
78+
[weakService = std::weak_ptr { service }]() -> std::vector<std::shared_ptr<Task>> {
79+
if (auto mockService = weakService.lock())
80+
{
81+
++mockService->getTasksCount;
82+
}
7983
return {
8084
std::make_shared<Task>(response::IdType(getFakeTaskId()), "Don't forget", true)
8185
};
8286
},
83-
[mockService = result.get()]() -> std::vector<std::shared_ptr<Folder>> {
84-
++mockService->getUnreadCountsCount;
87+
[weakService = std::weak_ptr { service }]() -> std::vector<std::shared_ptr<Folder>> {
88+
if (auto mockService = weakService.lock())
89+
{
90+
++mockService->getUnreadCountsCount;
91+
}
8592
return {
8693
std::make_shared<Folder>(response::IdType(getFakeFolderId()), "\"Fake\" Inbox", 3)
8794
};
8895
});
89-
auto mutation = std::make_shared<Mutation>(
96+
}
97+
98+
std::shared_ptr<Mutation> mock_mutation() noexcept
99+
{
100+
return std::make_shared<Mutation>(
90101
[](CompleteTaskInput&& input) -> std::shared_ptr<CompleteTaskPayload> {
91102
return std::make_shared<CompleteTaskPayload>(
92103
std::make_shared<Task>(std::move(input.id), "Mutated Task!", *(input.isComplete)),
93104
std::move(input.clientMutationId));
94105
});
95-
auto subscription = std::make_shared<NextAppointmentChange>(
106+
}
107+
108+
std::shared_ptr<NextAppointmentChange> mock_subscription() noexcept
109+
{
110+
return std::make_shared<NextAppointmentChange>(
96111
[](const std::shared_ptr<service::RequestState>&) -> std::shared_ptr<Appointment> {
97112
return { std::make_shared<Appointment>(response::IdType(getFakeAppointmentId()),
98113
"tomorrow",
99114
"Lunch?",
100115
true) };
101116
});
117+
}
118+
119+
std::shared_ptr<TodayMockService> mock_service() noexcept
120+
{
121+
auto result = std::make_shared<TodayMockService>();
102122

103-
result->service = std::make_shared<Operations>(std::move(query),
104-
std::move(mutation),
105-
std::move(subscription));
123+
result->service =
124+
std::make_shared<Operations>(mock_query(result), mock_mutation(), mock_subscription());
106125

107126
return result;
108127
}

samples/today/TodayMock.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct TodayMockService
3939
std::size_t getUnreadCountsCount {};
4040
};
4141

42-
std::unique_ptr<TodayMockService> mock_service() noexcept;
42+
std::shared_ptr<TodayMockService> mock_service() noexcept;
4343

4444
struct RequestState : service::RequestState
4545
{

0 commit comments

Comments
 (0)