Skip to content

REST JSON

NSmithy supports two REST JSON protocols. Both generate a typed .NET client and an ASP.NET Core minimal API server, and both use Smithy HTTP binding traits. Their simplest operations can look identical on the wire, but the protocols are not equivalent.

Choose restJson1 for most new services. It has a broader wire contract, a larger interoperability surface, protocol-defined streaming, and AWS-compatible error handling.

Choose simpleRestJson when you need compatibility with Alloy or Smithy4s, or when your model uses Alloy JSON features such as @discriminated and @jsonUnknown.

ProtocolTraitBest fit
AWS restJson1aws.protocols#restJson1General REST APIs, broad Smithy tooling support, streaming, or AWS-compatible services
simpleRestJsonalloy#simpleRestJsonAlloy and Smithy4s interoperability, with a deliberately smaller JSON-only wire contract

Coverage and maturity are tracked on the Protocol Status page.

AreasimpleRestJsonrestJson1
HTTP bindingsStandard Smithy REST bindingsStandard Smithy REST bindings
Structured bodiesJSONJSON
@httpPayloadJSON values, including JSON-encoded stringsJSON structures and documents, plus raw strings and blobs with media-type-aware content types
StreamingNot defined by the Alloy protocolStreaming blobs and Amazon Event Stream input, output, and duplex operations
Request body controlsJSON body rules@requestCompression and @httpChecksumRequired
Error typeX-Error-Type, with __type accepted by clientsX-Amzn-Errortype, plus compatible __type and code body fields
Error compatibilityNormalizes common namespace and qualifier formsAccepts more discriminator locations and normalizes AWS namespace and qualifier forms
JSON traitsAlloy traits including @discriminated and @jsonUnknownStandard Smithy and AWS JSON rules

The shared part is useful but small: ordinary structure members are serialized as JSON, and the standard HTTP traits decide what moves into the URI, query string, headers, status code, or payload. restJson1 adds the transport behavior needed by a wider range of services.

Apply the protocol trait to the service and @http to each operation. The example uses restJson1:

$version: "2"
namespace example.weather
use aws.protocols#restJson1
@restJson1
service Weather {
version: "2026-01-01"
operations: [GetCity]
}
@readonly
@http(method: "GET", uri: "/cities/{cityId}")
operation GetCity {
input := {
@required
@httpLabel
cityId: String
}
output := {
@required
name: String
}
errors: [NoSuchResource]
}
@error("client")
structure NoSuchResource {
@required
resourceType: String
}

For simpleRestJson, replace the import and service trait with alloy#simpleRestJson and @simpleRestJson. That swap is safe while the model uses only the shared feature set.

Members without an explicit HTTP binding are serialized in the JSON body.

TraitLocation
@httpLabelURI path segment
@httpQueryQuery string
@httpQueryParamsOpen-ended query string parameters
@httpHeaderRequest or response header
@httpPrefixHeadersHeaders with a modeled prefix
@httpResponseCodeResponse status code
@httpPayloadEntire request or response body

For an operation that only uses the shared feature set, both protocols produce the same request and response:

GET /cities/123 HTTP/1.1
Host: api.example.com
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{"name":"Seattle"}

This equivalence does not extend to raw payloads, event streams, request body modifiers, or error discrimination.

restJson1 supports more than JSON object bodies:

  • String payloads use raw UTF-8 text and text/plain by default.
  • Blob payloads use raw bytes and application/octet-stream by default.
  • @mediaType overrides the content type for an opaque payload.
  • @streaming blob payloads flow through the client and server without being buffered in memory.
  • Event stream inputs, outputs, and duplex operations use Amazon Event Stream framing with application/vnd.amazon.eventstream.
  • @requestCompression and @httpChecksumRequired can compress or checksum a buffered request body.

A simpleRestJson error carries its modeled shape name in X-Error-Type.

restJson1 servers write X-Amzn-Errortype. Clients also accept the error type from __type or code in a JSON response body. NSmithy removes namespace and qualifier forms used by AWS services before matching the value to a generated error type. This makes restJson1 clients tolerant of the error formats found across AWS and AWS-compatible services.

Add the model package for the selected protocol to smithy-build.json:

ProtocolMaven dependency
simpleRestJsoncom.disneystreaming.alloy:alloy-core:0.3.38
restJson1software.amazon.smithy:smithy-aws-traits:1.73.0
SurfacePackages
ClientNSmithy.Client, NSmithy.Codecs.Json, NSmithy.Protocols.RestJson
ServerNSmithy.Server.AspNetCore

The server package includes the REST JSON protocol and JSON codec transitively.

Both protocols generate the same application-facing API: a typed client and one handler interface per service. The selected protocol controls routing, serialization, streaming, and error dispatch without changing handler code. See the Protocols Overview for the client and server pattern.

restJson1 is useful outside AWS. When calling AWS itself, the request normally also needs SigV4 signing, regional endpoint resolution, credentials, retries, and service-specific endpoint rules. NSmithy provides early SigV4 support and a standard credential chain, but it does not yet cover the complete AWS SDK runtime. See Authentication and the AWS Protocols Overview.