Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS AppSync GraphQL input validation - ignore extra fields?

I have an input type in my schema that specifies lots of attributes, as it's intended to do. The issue is that what I'm sending to the mutation that will persist these objects is an object with arbitrary fields that may change. As it stands, if I send attributes not specified in the schema, I get the error:

Validation error of type WrongType: argument 'input' with value (...)
   contains a field not in 'BotInput': 'ext_gps' @ 'setBot'

Concretely, my input type did not specify the attribute exp_gps, and that field was provided.

My Question

Is there a way to make it so the input validation simply ignores any attributes not in the schema, so that it continues to perform the mutation with only whatever was specified in the schema? It'll be often that I don't want to persist the additional attributes, so dropping them is fine, as long as the other attributes get added.

like image 665
rodrigo-silveira Avatar asked Nov 16 '25 22:11

rodrigo-silveira


1 Answers

GraphQL does not support arbitrary fields, there is a RFC to support a Map type but it has not been merged/approved into the specification.

I see two possible workarounds that both require to change your schema a little bit.

Say you have the following schema:

type Mutation {
 saveBot(input: BotInput) : Boolean
}

input BotInput {
 id: ID!
 title: String
}

and the input object is:

{
 "id": "123",
 "title": "GoogleBot",
 "unrelated": "field",
 "ext_gps": "else"
}

Option 1: Pass the arbitrary fields as AWSJSON

You would change your schema to:

type Mutation {
 saveBot(input: BotInput) : Boolean
}

input BotInput {
 id: ID!
 title: String
 arbitraryFields: AWSJSON  // this will contain all the arbitrary fields in a json string, provided your clients can pluck them from the original object, make a map out of them and json serialize it. 
}

So the input in our example would be now:

{
 "id": "123",
 "title": "GoogleBot",
 "arbitraryFields": "{\"unrelated\": \"field\", \"ext_gps\": \"else\"}"
}

In your resolver, you could take the arbitraryFields string, deserialize it, and hydrate the values on the BotInput object before passing it to the data source.

Option 2: Pass the input as AWSJSON

The principle is the same but you pass the entire BotInput as AWSJSON.

type Mutation {
 saveBot(input: AWSJSON) : Boolean
}

You don't have to do the resolver hydration and you don't have to change your client, but you lose the GraphQL type validation as the whole BotInput is now a blob.

like image 148
Tinou Avatar answered Nov 18 '25 16:11

Tinou



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!