aws-amplify / aws-amplify/amplify-android
GraphQL model helpers cannot specify an auth mode per request
- Dominant language
- Java
- Stars
- 287
- Forks
- 132
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 45
Description
### Describe the feature request
`ModelQuery`, `ModelMutation` and `ModelSubscription` provide no way to select an authorization mode for the request they build. Amplify Swift and Amplify Flutter both support this on their equivalent helpers, so this is a parity gap.
Android does support per-request auth at the *operation* layer — `AppSyncGraphQLRequest` carries an `authorizationType` and its builder can set it — but none of the model helpers expose it. A caller who uses the helpers therefore always gets the API's default auth mode, with no way to override it.
**Language and async model:** Kotlin, Java
**Amplify category:** GraphQL API
**Affected module:** `com.amplifyframework:aws-api-appsync`
### Current behaviour
There is no auth-mode parameter anywhere in the three helpers:
```
$ grep -rc "authMode\|authorizationType\|AuthorizationType" \
aws-api-appsync/src/main/java/com/amplifyframework/api/graphql/model/Model{Query,Mutation,Subscription}.kt
0
0
0
```
So the only route today is to bypass the helpers and build the request by hand, which means giving up the selection-set generation they exist to provide.
### Parity evidence
Verified against the current sources of both repos rather than from documentation.
**Amplify Swift** — `authMode: AWSAuthorizationType?` is threaded through the helpers in [`AWSPluginsCore/Model/GraphQLRequest/GraphQLRequest+Model.swift`](https://github.com/aws-amplify/amplify-swift/blob/main/AmplifyPlugins/Core/AWSPluginsCore/Model/GraphQLRequest/GraphQLRequest%2BModel.swift) (35 occurrences), and `GraphQLRequest` itself carries `authMode`.
**Amplify Flutter** — `GraphQLRequest.authorizationMode: APIAuthorizationType?` in [`amplify_core`](https://github.com/aws-amplify/amplify-flutter/blob/main/packages/amplify_core/lib/src/types/api/graphql/graphql_request.dart), threaded through the helpers in `amplify_api_dart/lib/src/graphql/model_helpers/`: `model_queries.dart` (4), `model_mutations.dart` (8), `model_subscriptions.dart` (6).
### Relationship to #2210
This is **not** #2210. That issue is *"Add authentication support for SimpleGraphQLRequest"* and concerns raw/custom GraphQL documents — a different type in a different module. The two gaps were conflated previously, so to be explicit:
| | Gap | Type affected | Tracked by |
|---|---|---|---|
| A | Raw/custom documents take no auth mode | `SimpleGraphQLRequest` (`core`) | #2210 |
| B | Model helpers take no auth mode | `ModelQuery` / `ModelMutation` / `ModelSubscription` (`aws-api-appsync`) | this issue |
Fixing #2210 does not fix this, and vice versa.
### Two possible approaches
Both are viable; the tradeoff is discoverability versus surface area. Recording the measurements so the choice can be made on evidence.
#### Option 1 — add an auth-mode parameter to each helper overload
Matches Swift and Flutter directly, and is the most discoverable: the parameter shows up in autocomplete right where the request is built.
```kotlin
ModelQuery.get(Todo::class.java, "id-123", authMode = AuthorizationType.AMAZON_COGNITO_USER_POOLS)
```
Cost and risk, measured against the current sources:
- **26 public functions** would need the new parameter — `ModelQuery` 8, `ModelMutation` 10, `ModelSubscription` 8.
- **15 of them take a trailing `includes` lambda** (`ModelQuery` 6, `ModelMutation` 5, `ModelSubscription` 4). Appending a parameter *after* `includes` would break every Kotlin caller using trailing-lambda syntax, so a new parameter has to be inserted *before* it.
- Inserting before `includes` is source-compatible for named arguments but changes positional-argument call sites. Note that none of these functions is annotated `@JvmOverloads` today, so there are no generated Java overloads to worry about — the Java surface is whatever is declared.
#### Option 2 — one composable extension on `GraphQLRequest`
```kotlin
fun GraphQLRequest.withAuthorizationType(type: AuthorizationType): GraphQLRequest
```
```kotlin
ModelQuery.get(Todo::class.java, "id-123")
.withAuthorizationType(AuthorizationType.AMAZON_COGNITO_USER_POOLS)
```
It would wrap the already-public `AppSyncGraphQLRequest.newBuilder().authorizationType(...)`.
- Adds **one** symbol instead of touching 26.
- Cannot break a trailing-lambda caller, because no existing signature changes.
- Works for raw requests too, so it would also address gap A / #2210 for callers holding a `GraphQLRequest`.
- Less discoverable than a named parameter, and diverges from how Swift and Flutter express it — which matters if cross-platform documentation is meant to read the same.
- Needs a decision on the non-`AppSyncGraphQLRequest` case: return the request unchanged, or fail.
### Additional information
Filed by a maintainer while auditing cross-platform API parity, so the customer-environment fields of the template are not applicable. Reproducible against the current `main`.
Contributor guide
Research direction
Start with aws-api-appsync/src/main/java/com/amplifyframework/api/graphql/model/ModelQuery.kt, ModelMutation.kt, and ModelSubscription.kt, then read AppSyncGraphQLRequest and its authorizationType builder. Compare the two approaches described in the issue, resolve the API-surface tradeoffs, and verify that model-helper requests can select an auth mode without breaking existing callers.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, java, kotlin
- Domain
- api
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100