Skip to content

Commit 35274d5

Browse files
committed
fix: #297 only require 1 field per Subscription
1 parent 173fb57 commit 35274d5

14 files changed

+410
-56
lines changed

include/SchemaGenerator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ class [[nodiscard("unnecessary construction")]] Generator
4949
std::ostream& moduleFile, std::string_view objectNamespace, std::string_view cppType) const;
5050
void outputObjectImplements(std::ostream& headerFile, const ObjectType& objectType) const;
5151
void outputObjectStubs(std::ostream& headerFile, const ObjectType& objectType) const;
52-
void outputObjectDeclaration(
53-
std::ostream& headerFile, const ObjectType& objectType, bool isQueryType) const;
52+
void outputObjectDeclaration(std::ostream& headerFile, const ObjectType& objectType,
53+
bool isQueryType, bool isSubscriptionType) const;
5454
[[nodiscard("unnecessary memory copy")]] std::string getFieldDeclaration(
5555
const InputField& inputField) const noexcept;
5656
[[nodiscard("unnecessary memory copy")]] std::string getFieldDeclaration(

samples/learn/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ add_library(star_wars STATIC
1111
QueryData.cpp
1212
ReviewData.cpp
1313
MutationData.cpp
14-
StarWarsData.cpp)
14+
StarWarsData.cpp
15+
SubscriptionData.cpp)
1516
target_link_libraries(star_wars PUBLIC learn_schema)
1617
target_include_directories(star_wars INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
1718

samples/learn/StarWarsData.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "MutationData.h"
99
#include "QueryData.h"
1010
#include "ReviewData.h"
11+
#include "SubscriptionData.h"
1112

1213
using namespace std::literals;
1314

@@ -113,7 +114,9 @@ std::shared_ptr<service::Request> GetService() noexcept
113114
auto query =
114115
std::make_shared<learn::Query>(std::move(heroes), std::move(humans), std::move(droids));
115116
auto mutation = std::make_shared<learn::Mutation>();
116-
auto service = std::make_shared<learn::Operations>(std::move(query), std::move(mutation));
117+
auto service = std::make_shared<learn::Operations>(std::move(query),
118+
std::move(mutation),
119+
std::shared_ptr<learn::Subscription> {});
117120

118121
return service;
119122
}

samples/learn/SubscriptionData.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#include "CharacterObject.h"
5+
6+
#include "SubscriptionData.h"
7+
8+
namespace graphql::learn {
9+
10+
Subscription::Subscription() noexcept
11+
{
12+
}
13+
14+
std::shared_ptr<object::Character> Subscription::getCharacterChanged() const noexcept
15+
{
16+
return {};
17+
}
18+
19+
} // namespace graphql::learn

samples/learn/SubscriptionData.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#pragma once
5+
6+
#ifndef SUBSCRIPTIONDATA_H
7+
#define SUBSCRIPTIONDATA_H
8+
9+
#include "SubscriptionObject.h"
10+
11+
namespace graphql::learn {
12+
13+
namespace object {
14+
15+
class Character;
16+
17+
} // namespace object
18+
19+
class Subscription
20+
{
21+
public:
22+
explicit Subscription() noexcept;
23+
24+
std::shared_ptr<object::Character> getCharacterChanged() const noexcept;
25+
};
26+
27+
} // namespace graphql::learn
28+
29+
#endif // SUBSCRIPTIONDATA_H

samples/learn/schema/StarWarsSchema.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "QueryObject.h"
77
#include "MutationObject.h"
8+
#include "SubscriptionObject.h"
89

910
#include "graphqlservice/internal/Schema.h"
1011

@@ -145,13 +146,15 @@ ReviewInput& ReviewInput::operator=(ReviewInput&& other) noexcept
145146
return *this;
146147
}
147148

148-
Operations::Operations(std::shared_ptr<object::Query> query, std::shared_ptr<object::Mutation> mutation)
149+
Operations::Operations(std::shared_ptr<object::Query> query, std::shared_ptr<object::Mutation> mutation, std::shared_ptr<object::Subscription> subscription)
149150
: service::Request({
150151
{ service::strQuery, query },
151-
{ service::strMutation, mutation }
152+
{ service::strMutation, mutation },
153+
{ service::strSubscription, subscription }
152154
}, GetSchema())
153155
, _query(std::move(query))
154156
, _mutation(std::move(mutation))
157+
, _subscription(std::move(subscription))
155158
{
156159
}
157160

@@ -173,6 +176,8 @@ void AddTypesToSchema(const std::shared_ptr<schema::Schema>& schema)
173176
schema->AddType(R"gql(Review)gql"sv, typeReview);
174177
auto typeMutation = schema::ObjectType::Make(R"gql(Mutation)gql"sv, R"md()md"sv);
175178
schema->AddType(R"gql(Mutation)gql"sv, typeMutation);
179+
auto typeSubscription = schema::ObjectType::Make(R"gql(Subscription)gql"sv, R"md()md"sv);
180+
schema->AddType(R"gql(Subscription)gql"sv, typeSubscription);
176181

177182
typeEpisode->AddEnumValues({
178183
{ service::s_namesEpisode[static_cast<std::size_t>(learn::Episode::NEW_HOPE)], R"md()md"sv, std::nullopt },
@@ -192,9 +197,11 @@ void AddTypesToSchema(const std::shared_ptr<schema::Schema>& schema)
192197
AddQueryDetails(typeQuery, schema);
193198
AddReviewDetails(typeReview, schema);
194199
AddMutationDetails(typeMutation, schema);
200+
AddSubscriptionDetails(typeSubscription, schema);
195201

196202
schema->AddQueryType(typeQuery);
197203
schema->AddMutationType(typeMutation);
204+
schema->AddSubscriptionType(typeSubscription);
198205
}
199206

200207
std::shared_ptr<schema::Schema> GetSchema()

samples/learn/schema/StarWarsSchema.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,27 +81,30 @@ class Droid;
8181
class Query;
8282
class Review;
8383
class Mutation;
84+
class Subscription;
8485

8586
} // namespace object
8687

8788
class [[nodiscard("unnecessary construction")]] Operations final
8889
: public service::Request
8990
{
9091
public:
91-
explicit Operations(std::shared_ptr<object::Query> query, std::shared_ptr<object::Mutation> mutation);
92+
explicit Operations(std::shared_ptr<object::Query> query, std::shared_ptr<object::Mutation> mutation, std::shared_ptr<object::Subscription> subscription);
9293

93-
template <class TQuery, class TMutation>
94-
explicit Operations(std::shared_ptr<TQuery> query, std::shared_ptr<TMutation> mutation)
94+
template <class TQuery, class TMutation, class TSubscription = service::SubscriptionPlaceholder>
95+
explicit Operations(std::shared_ptr<TQuery> query, std::shared_ptr<TMutation> mutation, std::shared_ptr<TSubscription> subscription = {})
9596
: Operations {
9697
std::make_shared<object::Query>(std::move(query)),
97-
std::make_shared<object::Mutation>(std::move(mutation))
98+
std::make_shared<object::Mutation>(std::move(mutation)),
99+
subscription ? std::make_shared<object::Subscription>(std::move(subscription)) : std::shared_ptr<object::Subscription> {}
98100
}
99101
{
100102
}
101103

102104
private:
103105
std::shared_ptr<object::Query> _query;
104106
std::shared_ptr<object::Mutation> _mutation;
107+
std::shared_ptr<object::Subscription> _subscription;
105108
};
106109

107110
void AddCharacterDetails(const std::shared_ptr<schema::InterfaceType>& typeCharacter, const std::shared_ptr<schema::Schema>& schema);
@@ -111,6 +114,7 @@ void AddDroidDetails(const std::shared_ptr<schema::ObjectType>& typeDroid, const
111114
void AddQueryDetails(const std::shared_ptr<schema::ObjectType>& typeQuery, const std::shared_ptr<schema::Schema>& schema);
112115
void AddReviewDetails(const std::shared_ptr<schema::ObjectType>& typeReview, const std::shared_ptr<schema::Schema>& schema);
113116
void AddMutationDetails(const std::shared_ptr<schema::ObjectType>& typeMutation, const std::shared_ptr<schema::Schema>& schema);
117+
void AddSubscriptionDetails(const std::shared_ptr<schema::ObjectType>& typeSubscription, const std::shared_ptr<schema::Schema>& schema);
114118

115119
std::shared_ptr<schema::Schema> GetSchema();
116120

samples/learn/schema/StarWarsSchema.ixx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export import GraphQL.StarWars.DroidObject;
1515
export import GraphQL.StarWars.QueryObject;
1616
export import GraphQL.StarWars.ReviewObject;
1717
export import GraphQL.StarWars.MutationObject;
18+
export import GraphQL.StarWars.SubscriptionObject;
1819

1920
export namespace graphql::learn {
2021

@@ -32,6 +33,7 @@ using learn::AddDroidDetails;
3233
using learn::AddQueryDetails;
3334
using learn::AddReviewDetails;
3435
using learn::AddMutationDetails;
36+
using learn::AddSubscriptionDetails;
3537

3638
using learn::GetSchema;
3739

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
// WARNING! Do not edit this file manually, your changes will be overwritten.
5+
6+
#include "SubscriptionObject.h"
7+
#include "CharacterObject.h"
8+
9+
#include "graphqlservice/internal/Schema.h"
10+
11+
#include "graphqlservice/introspection/IntrospectionSchema.h"
12+
13+
#include <algorithm>
14+
#include <functional>
15+
#include <stdexcept>
16+
#include <unordered_map>
17+
18+
using namespace std::literals;
19+
20+
namespace graphql::learn {
21+
namespace object {
22+
23+
Subscription::Subscription(std::unique_ptr<const Concept> pimpl) noexcept
24+
: service::Object{ getTypeNames(), getResolvers() }
25+
, _pimpl { std::move(pimpl) }
26+
{
27+
}
28+
29+
service::TypeNames Subscription::getTypeNames() const noexcept
30+
{
31+
return {
32+
R"gql(Subscription)gql"sv
33+
};
34+
}
35+
36+
service::ResolverMap Subscription::getResolvers() const noexcept
37+
{
38+
return {
39+
{ R"gql(__typename)gql"sv, [this](service::ResolverParams&& params) { return resolve_typename(std::move(params)); } },
40+
{ R"gql(newEpisode)gql"sv, [this](service::ResolverParams&& params) { return resolveNewEpisode(std::move(params)); } },
41+
{ R"gql(characterChanged)gql"sv, [this](service::ResolverParams&& params) { return resolveCharacterChanged(std::move(params)); } }
42+
};
43+
}
44+
45+
void Subscription::beginSelectionSet(const service::SelectionSetParams& params) const
46+
{
47+
_pimpl->beginSelectionSet(params);
48+
}
49+
50+
void Subscription::endSelectionSet(const service::SelectionSetParams& params) const
51+
{
52+
_pimpl->endSelectionSet(params);
53+
}
54+
55+
service::AwaitableResolver Subscription::resolveCharacterChanged(service::ResolverParams&& params) const
56+
{
57+
std::unique_lock resolverLock(_resolverMutex);
58+
service::SelectionSetParams selectionSetParams { static_cast<const service::SelectionSetParams&>(params) };
59+
auto directives = std::move(params.fieldDirectives);
60+
auto result = _pimpl->getCharacterChanged(service::FieldParams { std::move(selectionSetParams), std::move(directives) });
61+
resolverLock.unlock();
62+
63+
return service::ModifiedResult<Character>::convert(std::move(result), std::move(params));
64+
}
65+
66+
service::AwaitableResolver Subscription::resolveNewEpisode(service::ResolverParams&& params) const
67+
{
68+
std::unique_lock resolverLock(_resolverMutex);
69+
service::SelectionSetParams selectionSetParams { static_cast<const service::SelectionSetParams&>(params) };
70+
auto directives = std::move(params.fieldDirectives);
71+
auto result = _pimpl->getNewEpisode(service::FieldParams { std::move(selectionSetParams), std::move(directives) });
72+
resolverLock.unlock();
73+
74+
return service::ModifiedResult<Episode>::convert(std::move(result), std::move(params));
75+
}
76+
77+
service::AwaitableResolver Subscription::resolve_typename(service::ResolverParams&& params) const
78+
{
79+
return service::Result<std::string>::convert(std::string{ R"gql(Subscription)gql" }, std::move(params));
80+
}
81+
82+
} // namespace object
83+
84+
void AddSubscriptionDetails(const std::shared_ptr<schema::ObjectType>& typeSubscription, const std::shared_ptr<schema::Schema>& schema)
85+
{
86+
typeSubscription->AddFields({
87+
schema::Field::Make(R"gql(characterChanged)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(Character)gql"sv))),
88+
schema::Field::Make(R"gql(newEpisode)gql"sv, R"md()md"sv, std::nullopt, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(Episode)gql"sv)))
89+
});
90+
}
91+
92+
} // namespace graphql::learn

0 commit comments

Comments
 (0)