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

Fusion: Added support for basic argument forwarding #5314

Merged
merged 1 commit into from
Aug 18, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public async Task<IQueryResult> ExecuteAsync(
var rootWorkItem = new WorkItem(rootSelectionSet, rootResult);
context.Fetch.Add(rootWorkItem);

// introspection
// introspection ... needs to be integrated into the execution plan.
if (context.Plan.HasIntrospectionSelections)
{
var rootSelections = rootSelectionSet.Selections;
Expand All @@ -67,7 +67,7 @@ public async Task<IQueryResult> ExecuteAsync(
}
}

// federated stuff
// execute execution plan
while (context.Fetch.Count > 0)
{
await FetchAsync(context, cancellationToken).ConfigureAwait(false);
Expand Down Expand Up @@ -150,48 +150,42 @@ private void ComposeResult(
for (var i = 0; i < selections.Count; i++)
{
var selection = selections[i];
var selectionType = selection.Type;
var responseName = selection.ResponseName;
var field = selection.Field;

if (selection.Field.IsIntrospectionField &&
(selection.Field.Name.EqualsOrdinal(IntrospectionFields.Schema) ||
selection.Field.Name.EqualsOrdinal(IntrospectionFields.Type)))
if (!field.IsIntrospectionField)
{
continue;
}

var selectionResult = selectionResults[i];
var nullable = selection.TypeKind is not TypeKind.NonNull;
var namedType = selection.Type.NamedType();
var selectionResult = selectionResults[i];
var nullable = selection.TypeKind is not TypeKind.NonNull;
var namedType = selectionType.NamedType();

if (selection.Type.IsScalarType() || namedType.IsScalarType())
{
selectionSetResult.SetValueUnsafe(
i,
selection.ResponseName,
selectionResult.Single.Element,
nullable);
}
else if (selection.Type.IsEnumType() || namedType.IsEnumType())
{
// we might need to map the enum value!
selectionSetResult.SetValueUnsafe(
i,
selection.ResponseName,
selectionResult.Single.Element,
nullable);
}
else if (selection.Type.IsCompositeType())
{
selectionSetResult.SetValueUnsafe(
i,
selection.ResponseName,
ComposeObject(context, selection, selectionResult));
if (namedType.IsScalarType())
{
var value = selectionResult.Single.Element;
selectionSetResult.SetValueUnsafe(i, responseName, value, nullable);
}
else if (namedType.IsEnumType())
{
// we might need to map the enum value!
var value = selectionResult.Single.Element;
selectionSetResult.SetValueUnsafe(i, responseName, value, nullable);
}
else if (selectionType.IsCompositeType())
{
var value = ComposeObject(context, selection, selectionResult);
selectionSetResult.SetValueUnsafe(i, responseName, value);
}
else
{
var value = ComposeList(context, selection, selectionResult, selectionType);
selectionSetResult.SetValueUnsafe(i, responseName, value);
}
}
else
else if (field.Name.EqualsOrdinal(IntrospectionFields.TypeName))
{
selectionSetResult.SetValueUnsafe(
i,
selection.ResponseName,
ComposeList(context, selection, selectionResult, selection.Type));
var value = selection.DeclaringType.Name;
selectionSetResult.SetValueUnsafe(i, responseName, value, false);
}
}
}
Expand Down Expand Up @@ -300,9 +294,7 @@ private IReadOnlyList<Argument> CreateArguments(
ISelection selection,
SelectionResult selectionResult,
ObjectType typeMetadata)
{
return new List<Argument>();
}
=> Array.Empty<Argument>();

private static void ExtractSelectionResults(
SelectionResult parent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ private ISelectionNode CreateSelectionNode(
null,
new(binding.Name),
alias,
null,
Array.Empty<DirectiveNode>(),
Array.Empty<ArgumentNode>(),
selection.SyntaxNode.Required,
Array.Empty<DirectiveNode>(), // todo : not sure if we should pass down directives.
selection.SyntaxNode.Arguments,
selectionSetNode);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -708,8 +708,47 @@ public async Task StoreService_Me_Name_Reviews_Upc()
me {
name
reviews {
product {
upc
nodes {
product {
upc
}
}
}
}
}");

// act
var queryPlan = await BuildStoreServiceQueryPlanAsync(request);

// assert
var index = 0;
var snapshot = new Snapshot();
snapshot.Add(request, "User Request");

foreach (var executionNode in queryPlan.ExecutionNodes)
{
if (executionNode is RequestNode rn)
{
snapshot.Add(rn.Handler.Document, $"Request {++index}");
}
}

await snapshot.MatchAsync();
}

[Fact]
public async Task StoreService_Selection_With_Arguments()
{
// arrange
var request = Parse(
@"query Me {
me {
name
reviews(first: 1) {
nodes {
product {
upc
}
}
}
}
Expand Down Expand Up @@ -775,8 +814,10 @@ public async Task StoreService_Introspection_TypeName()
me {
name
reviews {
product {
__typename
nodes {
product {
__typename
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,102 @@
type Query {
me: User!
@fetch(select: "user(id: 1) { ... User }", schema: "accounts")
@fetch(select: "authorById(id: 1) { ... User }", schema: "reviews")
@source(schema: "accounts")
@source(schema: "reviews")
me: User!
@fetch(select: "user(id: 1) { ... User }", schema: "accounts")
@fetch(select: "authorById(id: 1) { ... User }", schema: "reviews")
userById(id: Int!): User
@variable(argument: "id", name: "userId")
@fetch(select: "user(id: $userId) { ... User }", schema: "accounts")
@fetch(select: "authorById(id: $userId) { ... User }", schema: "reviews")
}

type User
@source(schema: "reviews", name: "Author")
@variable(name: "userId", select: "id", schema: "accounts", type: "Int!")
@variable(name: "userId", select: "id", schema: "reviews", type: "Int!")
@fetch(select: "user(id: $userId) { ... User }", schema: "accounts")
@fetch(select: "authorById(id: $userId) { ... User }", schema: "reviews") {
type User
@source(schema: "reviews", name: "Author")
@variable(name: "userId", select: "id", schema: "accounts", type: "Int!")
@variable(name: "userId", select: "id", schema: "reviews", type: "Int!")
@fetch(select: "user(id: $userId) { ... User }", schema: "accounts")
@fetch(select: "authorById(id: $userId) { ... User }", schema: "reviews") {
id: Int!
@source(schema: "accounts")
@source(schema: "reviews")
@source(schema: "accounts")
@source(schema: "reviews")
name: String!
@source(schema: "accounts")
@source(schema: "accounts")
birthdate: DateTime!
@source(schema: "accounts")
@source(schema: "accounts")
username: String!
@source(schema: "accounts")
@source(schema: "reviews")
reviews: [Review]
@source(schema: "reviews")
@source(schema: "accounts")
@source(schema: "reviews")
reviews(
"Returns the first _n_ elements from the list."
first: Int
"Returns the elements in the list that come after the specified cursor."
after: String
"Returns the last _n_ elements from the list."
last: Int
"Returns the elements in the list that come before the specified cursor."
before: String) : ReviewsConnection
@source(schema: "reviews")
}

type Review
@variable(name: "reviewId", select: "id", schema: "reviews", type: "Int!")
@fetch(select: "reviewById(id: $reviewId) { ... Review }", schema: "reviews") {
@variable(name: "reviewId", select: "id", schema: "reviews", type: "Int!")
@fetch(select: "reviewById(id: $reviewId) { ... Review }", schema: "reviews") {
id: Int!
@source(schema: "reviews")
@source(schema: "reviews")
body: String!
@source(schema: "reviews")
@source(schema: "reviews")
author: User!
@source(schema: "reviews")
@source(schema: "reviews")
product: Product!
@source(schema: "reviews")
@source(schema: "reviews")
}

type ReviewsConnection {
"Information to aid in pagination."
pageInfo: PageInfo!
@source(schema: "reviews")
"A list of edges."
edges: [ReviewsEdge!]
@source(schema: "reviews")
"A flattened list of the nodes."
nodes: [Review!]
@source(schema: "reviews")
}

type Product
@variable(name: "productId", select: "upc", schema: "reviews", type: "Int!")
@fetch(select: "productById(upc: $productId) { ... Product }", schema: "reviews") {
type ReviewsEdge {
"A cursor for use in pagination."
cursor: String!
@source(schema: "reviews")
"The item at the end of the edge."
node: Review!
@source(schema: "reviews")
}

type Product
@variable(name: "productId", select: "upc", schema: "reviews", type: "Int!")
@fetch(select: "productById(upc: $productId) { ... Product }", schema: "reviews") {
upc: Int!
@source(schema: "reviews")
@source(schema: "reviews")
reviews: [Review!]!
@source(schema: "reviews")
@source(schema: "reviews")
}

"Information about pagination in a connection."
type PageInfo {
"Indicates whether more edges exist following the set defined by the clients arguments."
hasNextPage: Boolean!
@source(schema: "reviews")
"Indicates whether more edges exist prior the set defined by the clients arguments."
hasPreviousPage: Boolean!
@source(schema: "reviews")
"When paginating backwards, the cursor to continue."
startCursor: String
@source(schema: "reviews")
"When paginating forwards, the cursor to continue."
endCursor: String
@source(schema: "reviews")
}

schema
@httpClient(schema: "accounts", baseAddress: "http://localhost:5051")
@httpClient(schema: "reviews", baseAddress: "http://localhost:5054") {
@httpClient(schema: "accounts", baseAddress: "http://localhost:5051")
@httpClient(schema: "reviews", baseAddress: "http://localhost:5054") {
query: Query
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ query Me {
me {
name
reviews {
product {
__typename
nodes {
product {
__typename
}
}
}
}
Expand All @@ -17,8 +19,10 @@ Request 1
query Me_1 {
me: authorById(id: 1) {
reviews {
product {
__typename
nodes {
product {
__typename
}
}
}
__fusion_exports__1: id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ query Me {
me {
name
reviews {
product {
upc
nodes {
product {
upc
}
}
}
}
Expand All @@ -17,8 +19,10 @@ Request 1
query Me_1 {
me: authorById(id: 1) {
reviews {
product {
upc
nodes {
product {
upc
}
}
}
__fusion_exports__1: id
Expand Down
Loading