AWSAWS Certified Generative AI Developer - Professional2026-102.4 Implement FM API integrations
Put specialized routing in the right layer
Completed by the knowledge check
Learning objective
Implement specialized model routing with application logic, Step Functions, or API Gateway request transformations.
Core idea
A specialized route connects an approved request class to the model and adapter that can serve it. The implementation must own both the target decision and the request transformation. Changing a model identifier while retaining an incompatible body is not a working route.
Choose the layer from the work the route requires. Application code fits decisions that need runtime data, semantic classification, or model-specific adaptation. Step Functions fits explicit multistep branches with observable workflow state. API Gateway transformations fit bounded request reshaping and parameter selection within a configured integration. The routing policies themselves are covered in 2.4.7; here the decision is where to execute them.
How it works
Execute dynamic decisions in application code
An application router can validate a task class, enforce caller entitlements, select an approved adapter, and invoke the target. Keep the Bedrock invocation inside a compatible adapter rather than exposing model-specific fields to every caller. See 2.4.1 for SDK invocation interfaces and 1.3.7 for native payload validation.
Treat the route registry as a mapping from an application task to an approved target, serializer, and output validator. The registry is an application design, not an AWS service resource. A task such as document classification should resolve to that complete bundle rather than to a model name alone.
This layer can inspect runtime measurements, call a classifier, or apply business rules before invocation. It also owns the failure outcome for unsupported tasks. Do not silently redirect every unknown class to the most capable model: a default route might violate modality, cost, or processing-location requirements.
Keep the application’s route decision separate from model-generated instructions. A classifier response can propose an allowlisted task class, but it must not provide unrestricted model identifiers or integration endpoints. Validate the proposed class before the router selects a resource. Runtime IAM permissions should align with the approved targets, so a defective route cannot freely invoke unrelated models.
Application routing offers flexibility at the cost of code-level observability. Record the task class, selected target, route reason, and configuration revision around each invocation. Those fields make a routing failure distinguishable from a model failure without logging the full user content.
Execute explicit branches in Step Functions
A Step Functions Choice state selects the next state from validated workflow data. With JSONPath rules, Variable identifies the field, a comparison such as StringEquals tests its value, and Next names the destination state. AWS documents that these rules are evaluated in listed order and the first match wins.
Provide a Default destination for unsupported or uncertain classes. Without a matching rule or Default, the workflow fails because it cannot transition. A safe default can lead to a rejection or clarification path rather than to another inference invocation. Put a restrictive, specific rule before a broad rule when both could match the same request. See 2.1.6 for bounded workflow-state transitions.
Rules are evaluated in listed order, so the first match decides the next state and only an unmatched request reaches Default.
For direct Bedrock inference, the optimized integration uses arn:aws:states:::bedrock:invokeModel. A branch supplies ModelId and a model-specific Body; it is not a Converse message adapter under another name. Step Functions does not validate that native body. Validate the payload before the task, and validate the returned result before allowing downstream business actions.
The optimized integration supports a Body payload up to 256 KiB. Its Input.S3Uri option supplies input from S3 instead, and Body and Input are mutually exclusive. Output.S3Uri writes the response to S3 and replaces the response body with a reference to that location. These are Step Functions integration fields, not fields to copy into a direct Bedrock Runtime request.
Choose a workflow when classification, branching, inference, and post-processing need separate states that operators can inspect. Use existing Retry and Catch policies for task failures, but preserve the shared attempt budget described in 2.4.5. Adding another orchestration layer does not justify another independent retry allowance.
Transform bounded requests in API Gateway
API Gateway REST API mapping templates use Velocity Template Language (VTL). The template selected for the request’s content type can transform a public payload into the integration’s expected body. This can remove model-specific serialization from a caller when the mapping is small and stable.
Request overrides can conditionally change mapped parameters. For example, $context.requestOverride.path.MODEL_PARAMETER can supply an approved model value for a configured integration path parameter, and $context.requestOverride.header.HEADER_NAME can set a backend routing header. Here, MODEL_PARAMETER and HEADER_NAME stand for names in your integration configuration. The integration must already define the backend behavior those values control.
A path override is not a general mechanism for replacing the entire integration with an arbitrary endpoint. Similarly, a routing header does nothing unless the receiving backend interprets it. Use an allowlist of values, and keep authorization outside the mapping expression. A client-provided model field must not become an unrestricted path or header override.
AWS permits an override of a given parameter only once. Reassigning the same override repeatedly in one template can produce a 5XX response. Compute the selected value in a local template variable, then apply the override once.
Set the integration’s passthroughBehavior explicitly. WHEN_NO_MATCH passes an unmatched content type through without transformation. WHEN_NO_TEMPLATES permits passthrough only when no templates exist; once a template exists, an unmapped content type receives 415 Unsupported Media Type. NEVER rejects unmatched content types with 415, including when no templates exist. Choose the setting that prevents an untransformed body from reaching your backend.
Mapping templates do not provide the application’s metric-driven control loop or a durable multistep workflow. AWS recommends using a proxy integration instead of mapping-template transformations when possible. Move substantial routing logic into the backend when a template starts accumulating classifiers, state assumptions, or complex failure handling.
Key distinctions and trade-offs
The following implementations place different responsibilities at the route boundary:
| Implementation | Strong fit | Responsibility you retain |
|---|---|---|
| Application router | Runtime signals and specialized adapters | Route validation, telemetry, and recovery logic |
| Step Functions branches | Explicit multistep processing | Valid branch input, native bodies, and terminal outcomes |
| REST API mapping template | Small, deterministic payload or parameter changes | Integration configuration, allowlists, and passthrough behavior |
A Choice state selects workflow control flow. A VTL template reshapes a request or changes configured parameters. A model API performs inference. None of these responsibilities should be inferred from the name of another layer.
Architecture / decision scenario
An enterprise gateway serves extraction, summarization, and complex document analysis through one task-oriented contract. The team evaluates all three implementation choices rather than forcing every request through one router.
Simple summarization maps to an application adapter that selects an approved message-based target and validates the normalized response. Complex analysis needs classification, model invocation, and post-processing, so a Step Functions workflow branches on a validated task field. Its Default rejects unknown task classes. Large native input uses the optimized integration’s S3 input option rather than enlarging workflow state.
A legacy REST method needs only a fixed payload reshape and an allowlisted backend header. The team retains a VTL mapping for that narrow path. It applies the header override once and sets passthroughBehavior to NEVER, so unmapped content types receive 415 Unsupported Media Type. If that method later needs live latency-based selection, the decision moves into application logic rather than expanding the template into an undocumented control loop.
All paths retain the same external result contract, but each adapter validates its own native response. The team records the selected route before inference and preserves the identifier through post-processing, making a wrong branch diagnosable separately from a poor model answer.
Common exam traps
- Changing
ModelIdwithout changing an incompatible native body. - Assuming Step Functions validates the optimized integration’s
Body. - Omitting
Defaultwhen aChoicemight have no match. - Passing
Input.S3Urias though it were a direct Bedrock Runtime field. - Treating a parameter override as arbitrary backend endpoint switching.
- Leaving
passthroughBehavioratWHEN_NO_MATCHand assuming untransformed bodies cannot reach the backend.
What to remember
Use code for flexible decisions, workflow states for explicit multistep branches, and mapping templates for small configured transformations. Every route needs an approved target and a compatible adapter. Validate branch inputs and model outputs, respect the 256 KiB optimized-body boundary, and make unsupported routes terminate explicitly.
Knowledge check
A routing gateway must pick a target per request from live latency measurements, and each target needs its own serializer and output validator. Where should this routing run?
Choice state over the request’s task classChoice state branches on workflow data rather than live metrics, and a client-chosen override bypasses the allowlist.A Step Functions Choice state routes document requests. Its first rule sends any task starting with contract to general analysis; a later rule sends contract-redline to a specialized model. There is no Default. Redline requests reach general analysis, and unknown tasks fail the execution. What fixes both problems?
contract-redline rule first and add a Default to a rejection pathcontract-redline rule first and add a Default to general analysisRetry to the Choice state for unknown tasksCatch that sends failures to general analysisDefault , the state cannot transition and the execution fails; a Default to rejection or clarification ends unknown classes explicitly, rather than sending them to another inference path.A Step Functions task calls Bedrock through arn:aws:states:::bedrock:invokeModel. Some documents produce a native request body larger than 256 KiB, and those tasks fail. What should the workflow do?
Body fields in one taskInput.S3UriBody and Input.S3Uri , so either can carry the requestConverse message body to shrink the payloadBody of up to 256 KiB and offers Input.S3Uri for larger input; Body and Input are mutually exclusive. The integration takes the model’s native body, so a Converse message format is not an option there.A legacy REST method maps JSON requests to a backend through a VTL template. An XML request just reached the backend untransformed. The team requires that an untransformed body never reach the backend, even if a later refactor removes the method’s templates. Which passthroughBehavior should it set?
WHEN_NO_MATCHWHEN_NO_TEMPLATESNEVERWHEN_NO_MATCH forwards unmatched content types as they are, which is what happened. WHEN_NO_TEMPLATES rejects unmapped types with 415 only while a template exists and passes everything through once none do. NEVER rejects untransformed bodies in both cases.A specialized route is moved to a different model by changing its ModelId, keeping the existing native request body and response parser. The public task schema is unchanged. Requests now fail or return results the parser misreads. What should the change have updated?
References
- AWS, Choice workflow state.
- AWS, Invoke Amazon Bedrock with Step Functions.
- AWS, Mapping template transformations for REST APIs in API Gateway.
- AWS, Override your API’s request and response parameters and status codes for REST APIs in API Gateway.
- AWS, Mapping template reference for REST APIs in API Gateway.
- AWS, Method request behavior for payloads without mapping templates for REST APIs in API Gateway.