Skip to content

Commit 5b4a58f

Browse files
Handle non-nullable IDs for input types in resolver (aws#137)
Fixed issue where non-nullable id values were being passed as numbers in neptune query parameters by unwrapping non-nullable ID types for input types in resolver. Co-authored-by: Kris McGinnes <kris@mcginnes.io>
1 parent 5d051d2 commit 5b4a58f

File tree

3 files changed

+33
-5
lines changed

3 files changed

+33
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,5 @@ permissions and limitations under the License.
128128
* Updated Apollo subgraph to allow use of Federation 2 features.
129129
([#126](https://github.com/aws/amazon-neptune-for-graphql/pull/126))
130130
* Accommodated for special characters in edge labels to ensure proper Cypher
131-
translation ([#127](https://github.com/aws/amazon-neptune-for-graphql/pull/127))
131+
translation ([#127](https://github.com/aws/amazon-neptune-for-graphql/pull/127))
132+
* Accommodated for non-nullable IDs in resolver for input types ([#137](https://github.com/aws/amazon-neptune-for-graphql/pull/137))

src/test/templates/JSResolverOCHTTPS.test.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,27 @@ test('should inference query with mutation update node (Query0016)', () => {
660660
});
661661
});
662662

663+
test('should inference query with mutation update node from event', () => {
664+
const result = resolveGraphDBQueryFromEvent({
665+
field: 'updateAirport',
666+
arguments: {input: {_id: "22", city: "Seattle"}},
667+
selectionSet: gql`{ city }`.definitions[0].selectionSet,
668+
fragments: {}
669+
});
670+
expect(result).toMatchObject({
671+
query: 'MATCH (updateAirport_Airport)\n' +
672+
'WHERE ID(updateAirport_Airport) = $updateAirport_Airport__id\n' +
673+
'SET updateAirport_Airport.city = $updateAirport_Airport_city\n' +
674+
'RETURN {city: updateAirport_Airport.`city`}',
675+
parameters: {
676+
updateAirport_Airport_city: 'Seattle',
677+
updateAirport_Airport__id: '22'
678+
},
679+
language: 'opencypher',
680+
refactorOutput: null
681+
});
682+
});
683+
663684
test('should resolve mutation to connect nodes', () => {
664685
const query = 'mutation ConnectCountryToAirport {\n' +
665686
' connectCountryToAirportThroughContains(from_id: \"ee71c547-ea32-4573-88bc-6ecb31942a1e\", to_id: \"99cb3321-9cda-41b6-b760-e88ead3e1ea1\") {\n' +
@@ -1375,7 +1396,7 @@ test('should resolve mutation to update node with fragment', () => {
13751396
'elev: updateAirport_Airport.`elev`' +
13761397
'}',
13771398
parameters: {
1378-
updateAirport_Airport__id: 22,
1399+
updateAirport_Airport__id: '22',
13791400
updateAirport_Airport_city: "Seattle",
13801401
},
13811402
language: 'opencypher',

templates/JSResolverOCHTTPS.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ express or implied. See the License for the specific language governing
1010
permissions and limitations under the License.
1111
*/
1212

13-
import { astFromValue, buildASTSchema, GraphQLError, GraphQLID, GraphQLInputObjectType, parse, typeFromAST } from 'graphql';
13+
import { astFromValue, buildASTSchema, GraphQLError, GraphQLID, GraphQLInputObjectType, GraphQLNonNull, parse, typeFromAST } from 'graphql';
1414

1515
const useCallSubquery = false;
1616

@@ -64,11 +64,17 @@ export function resolveGraphDBQueryFromEvent(event) {
6464
const value = event.arguments[inputDef.name.value];
6565

6666
if (value) {
67-
const inputType = typeFromAST(schema, inputDef.type);
67+
let inputType = typeFromAST(schema, inputDef.type);
68+
if (inputType instanceof GraphQLNonNull && inputType.ofType) {
69+
// if non-null type, unwrap to the underlying type
70+
inputType = inputType.ofType;
71+
}
6872
const astValue = astFromValue(value, inputType);
6973
if (inputType instanceof GraphQLInputObjectType) {
7074
// retrieve an ID field which may not necessarily be named 'id'
71-
const idField = Object.values(inputType.getFields()).find(field => field.type.name === GraphQLID.name);
75+
const idField = Object.values(inputType.getFields()).find(
76+
// if field is of non-null type, check the underlying type as well
77+
field => field.type?.name === GraphQLID.name || field.type?.ofType?.name === GraphQLID.name);
7278
if (idField) {
7379
// check if id was an input arg
7480
const idValue = astValue.fields.find(f => f.name.value === idField.name);

0 commit comments

Comments
 (0)