aws-amplify / amplify-category-api

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development. This plugin provides functionality for the API category, allowing for the creation and management of GraphQL and REST based backends for your amplify project.
https://docs.amplify.aws/
Apache License 2.0
89 stars 79 forks source link

Allow custom query functions to accept an array of arguments #2913

Open ataylorme opened 2 months ago

ataylorme commented 2 months ago

Describe the feature you'd like to request

Allow a.query().arguments and .returns() to both accept arrays. This will allow custom query arguments mapped to Lambda handlers to allow the Lambda to process multiple requests in a single invocation, reducing network calls and cold starts.

In my specific case the user's identity is used to fetch an external API key and instantiate an external API client. Batching requests from the same user will make this much more efficient.

Currently the example below produces the error Property 'array' does not exist on type 'CustomType<{ fields: { action: ModelField<string, "required", undefined>; parameters: ModelField<string | number | boolean | object | any[], "required", undefined>; paginate: ModelField<...>; }; }>'

Notice how the return value may be an array, and does not produce an error, but the arguments cannot be an array.

MyCustomApiRequestResponse: a.customType({
    data: a.string(),
    rawResponse: a.string(),
    errors: a.string().array(),
}),

MyCustomApiRequest: a
    .query()
    .arguments({
        requests: a.customType({
            action: a.string().required(),
            parameters: a.json().required(),
            paginate: a.boolean().required(),
        }).array().required(),
    })
    .returns(a.ref('MyCustomApiRequestResponse').array())
    .handler(a.handler.function(myCustomApiRequest))
    .authorization(allow => [allow.authenticated()]),

Describe the solution you'd like

Support for custom query functions to accept an array of arguments modeled with customType

Describe alternatives you've considered

I have explored sending arguments as JSON or a string which gets parsed in the Lambda but in both cases validation and strict typing are lost.

Additional context

No response

Is this something that you'd be interested in working on?

Would this feature include a breaking change?

anni1236012 commented 2 months ago

+1 This is an important feature to have.

AnilMaktala commented 2 months ago

Hey @ataylorme, Thank you for bringing this to our attention. We have noted it as a feature request for the team to review in more detail.

jmarshall9120 commented 6 days ago

I don't even think you can do this:

MyCustomApiRequest: a
    .query()
    .arguments({
        requests: a.customType({
            action: a.string().required(),
            parameters: a.json().required(),
            paginate: a.boolean().required(),
        }),
    })
    .returns(a.ref('MyCustomApiRequestResponse').array())
    .handler(a.handler.function(myCustomApiRequest))
    .authorization(allow => [allow.authenticated()]),

A customType returns type in the arguments field returns this error:

Type 'RefType<SetTypeSubArg<RefTypeArgFactory<"MyCustomType">, "valueRequired", true>, "required", undefined>' is not assignable to type 'BaseModelField | EnumType<readonly string[]>'.
  Type 'RefType<SetTypeSubArg<RefTypeArgFactory<"MyCustomType">, "valueRequired", true>, "required", undefined>' is not assignable to type 'BaseModelField'.
    Types of property '[brandSymbol]' are incompatible.
      Type '"ref"' is not assignable to type '"modelField"'

This makes the arguments field even more useless in it's current for.