Continuing the discussion from Slash Lambda Fileds addGraphQLResolver missing args:
Overview
In a lambda function, we should be able to run graphql requests either queries or mutations. What we want to do next is to fetch from an API and update one field when we request another field. What we found out while doing this is that while we can do graphql queries and mutations, the JWT token is not being passed along. This results in problems because now we either have to include a hard coded token or remove the auth update rule to allow this to work from a lambda.
There may be another bug here with passing variables to the graphql query/mutation even if the variables are hard coded. I will test again on that point with a simpler example to confirm.
UPDATE: No this was not another bug. We resolved this part I believe.
Schema:
type Contact @auth(
update: { rule: "{$ROLE: { eq: \"ADMIN\" } }" }
) {
id: ID
name: String @search(by: [hash])
fromAPI: String
syncAPI: String @lambda
}
# Dgraph.Authorization {"VerificationKey":"My_S3cr3t!","Header":"token","Namespace":"https://my.app.com/claims","Algo":"HS256"}
JWT:
{
"https://my.app.com/claims": {
"ROLE": "ADMIN"
},
"iat": 1605923890,
"exp": 1767225600,
"iss": "myapp",
"sub": "john.doe"
}
signed:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczovL215LmFwcC5jb20vY2xhaW1zIjp7IlJPTEUiOiJBRE1JTiJ9LCJpYXQiOjE2MDU5MjM4OTAsImV4cCI6MTc2NzIyNTYwMCwiaXNzIjoibXlhcHAiLCJzdWIiOiJqb2huLmRvZSJ9.A2kpBagmpmI62hYTG-doCk3fxFhSF3PH_qdSo8jdIJI
Add Data
mutation {
addContact(input: [{
name: "Qux"
}]) {
numUids
contact {
id
name
fromAPI
}
}
}
response:
{
"data": {
"addContact": {
"numUids": 1,
"contact": [
{
"id": "0x7",
"name": "Qux",
"fromAPI": null
}
]
}
},
"extensions": {
"touched_uids": 7,
"tracing": {
"version": 1,
"startTime": "2021-01-14T19:50:52.329356205Z",
"endTime": "2021-01-14T19:50:52.334463966Z",
"duration": 5107780,
"execution": {
"resolvers": [
{
"path": [
"addContact"
],
"parentType": "Mutation",
"fieldName": "addContact",
"returnType": "AddContactPayload",
"startOffset": 101131,
"duration": 4979254,
"dgraph": [
{
"label": "mutation",
"startOffset": 148307,
"duration": 2474818
},
{
"label": "query",
"startOffset": 3679377,
"duration": 1373014
}
]
}
]
}
}
}
}
Update From Slash API Explorer:
passing in the JWT above as the header token
mutation {
updateContact(input: {
filter: {
name:{eq:"Qux"}
}
set: {
fromAPI: "quux"
}
}) {
numUids
contact {
id
name
fromAPI
}
}
}
response:
{
"data": {
"updateContact": {
"numUids": 1,
"contact": [
{
"id": "0x7",
"name": "Qux",
"fromAPI": "quux"
}
]
}
},
"extensions": {
"touched_uids": 9,
"tracing": {
"version": 1,
"startTime": "2021-01-14T20:00:17.206785379Z",
"endTime": "2021-01-14T20:00:17.211507046Z",
"duration": 4721686,
"execution": {
"resolvers": [
{
"path": [
"updateContact"
],
"parentType": "Mutation",
"fieldName": "updateContact",
"returnType": "UpdateContactPayload",
"startOffset": 96834,
"duration": 4599594,
"dgraph": [
{
"label": "mutation",
"startOffset": 217826,
"duration": 1988950
},
{
"label": "query",
"startOffset": 3456080,
"duration": 1206784
}
]
}
]
}
}
}
}
Lambda:
async function syncAPI({graphql}) {
const response = await graphql(`
mutation {
updateContact(input: {
filter: {
name:{eq:"Qux"}
}
set: {
fromAPI: "quuz"
}
}) {
numUids
contact {
id
name
fromAPI
}
}
}
`);
return JSON.stringify(response)
}
self.addGraphQLResolvers({
"Contact.syncAPI": syncAPI
})
Query from Slash API Explorer
query MyQuery {
queryContact(filter: {name: {eq: "Qux"}}) {
id
name
syncAPI
}
}
response:
{
"data": {
"queryContact": [
{
"id": "0x7",
"name": "Qux",
"syncAPI": "{\"data\":{\"updateContact\":{\"numUids\":0,\"contact\":[]}},\"extensions\":{\"touched_uids\":2,\"tracing\":{\"version\":1,\"startTime\":\"2021-01-14T20:06:21.767509161Z\",\"endTime\":\"2021-01-14T20:06:21.771172522Z\",\"duration\":3663351,\"execution\":{\"resolvers\":[{\"path\":[\"updateContact\"],\"parentType\":\"Mutation\",\"fieldName\":\"updateContact\",\"returnType\":\"UpdateContactPayload\",\"startOffset\":96515,\"duration\":3551855,\"dgraph\":[{\"label\":\"mutation\",\"startOffset\":131853,\"duration\":1378019},{\"label\":\"query\",\"startOffset\":2541768,\"duration\":1090889}]}]}}}}"
}
]
},
"extensions": {
"touched_uids": 4,
"tracing": {
"version": 1,
"startTime": "2021-01-14T20:06:21.742527393Z",
"endTime": "2021-01-14T20:06:21.77845642Z",
"duration": 35929029,
"execution": {
"resolvers": [
{
"path": [
"queryContact"
],
"parentType": "Query",
"fieldName": "queryContact",
"returnType": "[Contact]",
"startOffset": 99917,
"duration": 35803282,
"dgraph": [
{
"label": "query",
"startOffset": 234199,
"duration": 1638815
}
]
}
]
}
}
}
}
Notice numUids returned 0. No Contact was updated.
This would only be possible if the JWT was not passed through the lambda script.
Umm… @abhimanyusinghgaur, that is not true in my test case here.