-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(GraphQL): GraphQL now has lambda resolvers (#6574)
This PR adds `@lambda` directive in GraphQL, using which one can call Custom JavaScript resolvers. Now, alpha has a flag called `--graphql_lambda_url` which is used to set the URL of the lambda server. All the `@lambda` fields will be resolved through the lambda functions implemented on the given lambda server. RFC: https://discuss.dgraph.io/t/implement-custom-js-resolvers-in-graphql/9361 Lambda server: https://github.com/dgraph-io/dgraph-lambda (cherry picked from commit 2f3d7f4) # Conflicts: # graphql/e2e/common/common.go # graphql/e2e/directives/docker-compose.yml # graphql/e2e/directives/schema.graphql # graphql/e2e/normal/docker-compose.yml # graphql/e2e/normal/schema.graphql # graphql/e2e/schema/generatedSchema.graphql # graphql/schema/gqlschema.go # graphql/schema/testdata/schemagen/output/authorization.graphql # graphql/schema/testdata/schemagen/output/comments-and-descriptions.graphql # graphql/schema/testdata/schemagen/output/custom-mutation.graphql # graphql/schema/testdata/schemagen/output/custom-nested-types.graphql # graphql/schema/testdata/schemagen/output/custom-query-mixed-types.graphql # graphql/schema/testdata/schemagen/output/custom-query-not-dgraph-type.graphql # graphql/schema/testdata/schemagen/output/custom-query-with-dgraph-type.graphql # graphql/schema/testdata/schemagen/output/deprecated.graphql # graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-on-concrete-type-with-interfaces.graphql # graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-with-interfaces.graphql # graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql # graphql/schema/testdata/schemagen/output/field-with-reverse-predicate-in-dgraph-directive.graphql # graphql/schema/testdata/schemagen/output/filter-cleanSchema-directLink.graphql # graphql/schema/testdata/schemagen/output/hasInverse-with-interface-having-directive.graphql # graphql/schema/testdata/schemagen/output/hasInverse-with-interface.graphql # graphql/schema/testdata/schemagen/output/hasInverse-with-type-having-directive.graphql # graphql/schema/testdata/schemagen/output/hasInverse.graphql # graphql/schema/testdata/schemagen/output/hasInverse_withSubscription.graphql # graphql/schema/testdata/schemagen/output/ignore-unsupported-directive.graphql # graphql/schema/testdata/schemagen/output/interface-with-dgraph-pred.graphql # graphql/schema/testdata/schemagen/output/interface-with-id-directive.graphql # graphql/schema/testdata/schemagen/output/interface-with-no-ids.graphql # graphql/schema/testdata/schemagen/output/interfaces-with-types-and-password.graphql # graphql/schema/testdata/schemagen/output/interfaces-with-types.graphql # graphql/schema/testdata/schemagen/output/no-id-field-with-searchables.graphql # graphql/schema/testdata/schemagen/output/no-id-field.graphql # graphql/schema/testdata/schemagen/output/password-type.graphql # graphql/schema/testdata/schemagen/output/searchables-references.graphql # graphql/schema/testdata/schemagen/output/searchables.graphql # graphql/schema/testdata/schemagen/output/single-type-with-enum.graphql # graphql/schema/testdata/schemagen/output/single-type.graphql # graphql/schema/testdata/schemagen/output/type-implements-multiple-interfaces.graphql # graphql/schema/testdata/schemagen/output/type-reference.graphql # graphql/schema/testdata/schemagen/output/type-with-arguments-on-field.graphql # graphql/schema/testdata/schemagen/output/type-with-custom-field-on-dgraph-type.graphql # graphql/schema/testdata/schemagen/output/type-with-custom-fields-on-remote-type.graphql # graphql/schema/testdata/schemagen/output/type-without-orderables.graphql
- Loading branch information
1 parent
158680a
commit c01690f
Showing
66 changed files
with
1,042 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
/* | ||
* Copyright 2020 Dgraph Labs, Inc. and Contributors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package common | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/dgraph-io/dgraph/testutil" | ||
) | ||
|
||
func lambdaOnTypeField(t *testing.T) { | ||
query := ` | ||
query { | ||
queryAuthor { | ||
name | ||
bio | ||
rank | ||
} | ||
}` | ||
params := &GraphQLParams{Query: query} | ||
resp := params.ExecuteAsPost(t, GraphqlURL) | ||
RequireNoGQLErrors(t, resp) | ||
|
||
expectedResponse := `{ | ||
"queryAuthor": [ | ||
{ | ||
"name":"Three Author", | ||
"bio":"My name is Three Author and I was born on 2001-01-01T00:00:00Z.", | ||
"rank":1 | ||
}, | ||
{ | ||
"name":"Ann Author", | ||
"bio":"My name is Ann Author and I was born on 2000-01-01T00:00:00Z.", | ||
"rank":3 | ||
}, | ||
{ | ||
"name":"Ann Other Author", | ||
"bio":"My name is Ann Other Author and I was born on 1988-01-01T00:00:00Z.", | ||
"rank":2 | ||
} | ||
] | ||
}` | ||
testutil.CompareJSON(t, expectedResponse, string(resp.Data)) | ||
} | ||
|
||
func lambdaOnInterfaceField(t *testing.T) { | ||
starship := addStarship(t) | ||
humanID := addHuman(t, starship.ID) | ||
droidID := addDroid(t) | ||
|
||
// when querying bio on Character (interface) we should get the bio constructed by the lambda | ||
// registered on Character.bio | ||
query := ` | ||
query { | ||
queryCharacter { | ||
name | ||
bio | ||
} | ||
}` | ||
params := &GraphQLParams{Query: query} | ||
resp := params.ExecuteAsPost(t, GraphqlURL) | ||
RequireNoGQLErrors(t, resp) | ||
|
||
expectedResponse := `{ | ||
"queryCharacter": [ | ||
{ | ||
"name":"Han", | ||
"bio":"My name is Han." | ||
}, | ||
{ | ||
"name":"R2-D2", | ||
"bio":"My name is R2-D2." | ||
} | ||
] | ||
}` | ||
testutil.CompareJSON(t, expectedResponse, string(resp.Data)) | ||
|
||
// TODO: this should work. At present there is a bug with @custom on interface field resolved | ||
// through a fragment on one of its types. We need to fix that first, then uncomment this test. | ||
|
||
// when querying bio on Human & Droid (type) we should get the bio constructed by the lambda | ||
// registered on Human.bio and Droid.bio respectively | ||
/*query = ` | ||
query { | ||
queryCharacter { | ||
name | ||
... on Human { | ||
bio | ||
} | ||
... on Droid { | ||
bio | ||
} | ||
} | ||
}` | ||
params = &GraphQLParams{Query: query} | ||
resp = params.ExecuteAsPost(t, GraphqlURL) | ||
RequireNoGQLErrors(t, resp) | ||
expectedResponse = `{ | ||
"queryCharacter": [ | ||
{ | ||
"name":"Han", | ||
"bio":"My name is Han. I have 10 credits." | ||
}, | ||
{ | ||
"name":"R2-D2", | ||
"bio":"My name is R2-D2. My primary function is Robot." | ||
} | ||
] | ||
}` | ||
testutil.CompareJSON(t, expectedResponse, string(resp.Data))*/ | ||
|
||
// cleanup | ||
cleanupStarwars(t, starship.ID, humanID, droidID) | ||
} | ||
|
||
func lambdaOnQueryUsingDql(t *testing.T) { | ||
query := ` | ||
query { | ||
authorsByName(name: "Ann Author") { | ||
name | ||
dob | ||
reputation | ||
} | ||
}` | ||
params := &GraphQLParams{Query: query} | ||
resp := params.ExecuteAsPost(t, GraphqlURL) | ||
RequireNoGQLErrors(t, resp) | ||
|
||
expectedResponse := `{ | ||
"authorsByName": [ | ||
{ | ||
"name":"Ann Author", | ||
"dob":"2000-01-01T00:00:00Z", | ||
"reputation":6.6 | ||
} | ||
] | ||
}` | ||
testutil.CompareJSON(t, expectedResponse, string(resp.Data)) | ||
} | ||
|
||
func lambdaOnMutationUsingGraphQL(t *testing.T) { | ||
// first, add the author using @lambda | ||
query := ` | ||
mutation { | ||
newAuthor(name: "Lambda") | ||
}` | ||
params := &GraphQLParams{Query: query} | ||
resp := params.ExecuteAsPost(t, GraphqlURL) | ||
RequireNoGQLErrors(t, resp) | ||
|
||
// let's get the author ID of the newly added author as returned by lambda | ||
var addResp struct { | ||
AuthorID string `json:"newAuthor"` | ||
} | ||
require.NoError(t, json.Unmarshal(resp.Data, &addResp)) | ||
|
||
// now, lets query the same author and verify that its reputation was set as 3.0 by lambda func | ||
query = ` | ||
query ($id: ID!){ | ||
getAuthor(id: $id) { | ||
name | ||
reputation | ||
} | ||
}` | ||
params = &GraphQLParams{Query: query, Variables: map[string]interface{}{"id": addResp.AuthorID}} | ||
resp = params.ExecuteAsPost(t, GraphqlURL) | ||
RequireNoGQLErrors(t, resp) | ||
|
||
expectedResponse := `{ | ||
"getAuthor": { | ||
"name":"Lambda", | ||
"reputation":3.0 | ||
} | ||
}` | ||
testutil.CompareJSON(t, expectedResponse, string(resp.Data)) | ||
|
||
// cleanup | ||
deleteAuthors(t, []string{addResp.AuthorID}, nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.