Inline io for examples (#61)

Inline input and output shapes for examples where possible.
This commit is contained in:
Hunter Mellema 2023-10-10 11:31:21 -06:00 committed by GitHub
parent 32ac02914b
commit eb326213f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 282 additions and 422 deletions

View File

@ -3,74 +3,57 @@ $version: "2.0"
namespace smithy.example
resource City {
identifiers: { cityId: CityId }
properties: {
coordinates: CityCoordinates
name: String
}
identifiers: {cityId: CityId}
properties: {coordinates: CityCoordinates, name: String}
read: GetCity
create: CreateCity
resources: [Forecast]
}
@readonly
@http(
method: "GET",
uri: "/city/{cityId}"
)
@http(method: "GET", uri: "/city/{cityId}")
operation GetCity {
input: GetCityInput,
output: GetCityOutput,
errors: [NoSuchResource]
input := for City {
@required
@httpLabel
$cityId
}
output := for City {
// "required" is used on output to indicate if the service
// will always provide a value for the member.
@required
$name
@required
$coordinates
}
errors: [
NoSuchResource
]
}
@input
structure GetCityInput for City {
// "cityId" provides the identifier for the resource and
// has to be marked as required.
@required
@httpLabel
$cityId
}
structure GetCityOutput for City {
// "required" is used on output to indicate if the service
// will always provide a value for the member.
@required
$name
@required
$coordinates
}
@http(
method: "POST",
uri: "/city"
)
@http(method: "POST", uri: "/city")
operation CreateCity {
input: CreateCityInput,
output: CreateCityOutput
}
input := for City {
@required
$name
@input
structure CreateCityInput for City {
@required
$name
@required
$coordinates
}
@required
$coordinates
}
output := for City {
@required
$cityId
@output
structure CreateCityOutput for City {
@required
$cityId
@required
$name
@required
$name
@required
$coordinates
@required
$coordinates
}
}
// "pattern" is a trait that constrains the string value
@ -84,5 +67,3 @@ structure CityCoordinates {
@required
longitude: Float
}

View File

@ -2,7 +2,6 @@ $version: "2.0"
namespace smithy.example
// "error" is a trait that is used to specialize
// a structure as an error.
@error("client")
@ -26,6 +25,3 @@ structure ServiceError {
@required
message: String
}

View File

@ -5,22 +5,16 @@ namespace smithy.example
// In Smithy, example values of input structure members and the
// corresponding output or error structure members for an operation
// are grouped together into one set of example values for an operation.
apply GetCity @examples(
[
{
title: "Get City Example",
documentation: "Gets a city with the ID 1234",
input: {
cityId: "1234"
},
title: "Get City Example"
documentation: "Gets a city with the ID 1234"
input: {cityId: "1234"}
output: {
name: "Seattle"
coordinates: {
latitude: 47.6,
longitude: 122.3
}
},
coordinates: {latitude: 47.6, longitude: 122.3}
}
}
]
)
@ -28,23 +22,17 @@ apply GetCity @examples(
apply CreateCity @examples(
[
{
title: "Create City Example",
documentation: "An example that creates a City Called Seattle",
title: "Create City Example"
documentation: "An example that creates a City Called Seattle"
input: {
name: "Seattle"
coordinates: {
latitude: 47.6,
longitude: 122.3
}
},
coordinates: {latitude: 47.6, longitude: 122.3}
}
output: {
cityId: "1234"
name: "Seattle"
coordinates: {
latitude: 47.6,
longitude: 122.3
}
},
coordinates: {latitude: 47.6, longitude: 122.3}
}
}
]
)

View File

@ -3,19 +3,15 @@ $version: "2.0"
namespace smithy.example
apply GetForecast @examples(
[
{
title: "Create City Example",
documentation: "An example that creates a City Called Seattle",
input: {
cityId: "1234"
},
output: {
rating: "SOMEWHAT_HAPPY",
forecast: {
"rain": 12.0
[
{
title: "Create City Example"
documentation: "An example that creates a City Called Seattle"
input: {cityId: "1234"}
output: {
rating: "SOMEWHAT_HAPPY"
forecast: {rain: 12.0}
}
},
}
]
}
]
)

View File

@ -3,48 +3,38 @@ $version: "2.0"
namespace smithy.example
resource Forecast {
identifiers: { cityId: CityId },
read: GetForecast,
identifiers: {cityId: CityId}
read: GetForecast
}
@readonly
@http(
method: "GET",
uri: "/city/{cityId}/forecast"
)
@http(method: "GET", uri: "/city/{cityId}/forecast")
operation GetForecast {
input: GetForecastInput
output: GetForecastOutput
}
input := for Forecast {
@required
@httpLabel
$cityId
}
// "cityId" provides the only identifier for the resource since
// a Forecast doesn't have its own.
@input
structure GetForecastInput for Forecast{
@required
@httpLabel
$cityId
}
@output
structure GetForecastOutput {
rating: Rating
forecast: ForecastResult
output := {
rating: Rating
forecast: ForecastResult
}
}
/// How happy do we expect this forecast to make you
enum Rating {
SUPER_HAPPY,
SOMEWHAT_HAPPY,
MEH,
NOT_SO_HAPPY,
SUPER_HAPPY
SOMEWHAT_HAPPY
MEH
NOT_SO_HAPPY
UNHAPPY
}
// Unions represent a `one-of` relationship. The forecast could be
// either `rain` with a float value or `sun` with an integer value
union ForecastResult {
rain: ChanceOfRain,
rain: ChanceOfRain
sun: UVIndex
}

View File

@ -5,8 +5,7 @@ namespace smithy.example
use aws.protocols#restJson1
/// Provides weather forecasts
@paginated(inputToken: "nextToken", outputToken: "nextToken",
pageSize: "pageSize")
@paginated(inputToken: "nextToken", outputToken: "nextToken", pageSize: "pageSize")
@restJson1
@title("Weather Service")
service Weather {
@ -18,18 +17,10 @@ service Weather {
}
@readonly
@http(
method: "GET",
uri: "/current-time"
)
@http(method: "GET", uri: "/current-time")
operation GetCurrentTime {
output: GetCurrentTimeOutput
output := {
@required
time: Timestamp
}
}
structure GetCurrentTimeOutput {
@required
time: Timestamp
}

View File

@ -3,11 +3,8 @@ $version: "2.0"
namespace smithy.example
resource City {
identifiers: { cityId: CityId }
properties: {
coordinates: CityCoordinates
name: String
}
identifiers: {cityId: CityId}
properties: {coordinates: CityCoordinates, name: String}
read: GetCity
create: CreateCity
resources: [Forecast]
@ -15,54 +12,48 @@ resource City {
@readonly
operation GetCity {
input: GetCityInput,
output: GetCityOutput,
errors: [NoSuchResource]
}
input := for City {
// "cityId" provides the identifier for the resource and
// has to be marked as required.
@required
@httpLabel
$cityId
}
@input
structure GetCityInput for City {
// "cityId" provides the identifier for the resource and
// has to be marked as required.
@required
@httpLabel
$cityId
}
output := for City{
// "required" is used on output to indicate if the service
// will always provide a value for the member.
@required
$name
structure GetCityOutput for City {
// "required" is used on output to indicate if the service
// will always provide a value for the member.
@required
$name
@required
$coordinates
}
@required
$coordinates
errors: [
NoSuchResource
]
}
operation CreateCity {
input: CreateCityInput,
output: CreateCityOutput
}
input := for City {
@required
$name
@input
structure CreateCityInput for City {
@required
$name
@required
$coordinates
}
@required
$coordinates
}
output := for City {
@required
$cityId
@output
structure CreateCityOutput for City {
@required
$cityId
@required
$name
@required
$name
@required
$coordinates
@required
$coordinates
}
}
// "pattern" is a trait that constrains the string value
@ -76,5 +67,3 @@ structure CityCoordinates {
@required
longitude: Float
}

View File

@ -2,7 +2,6 @@ $version: "2.0"
namespace smithy.example
// "error" is a trait that is used to specialize
// a structure as an error.
@error("client")
@ -23,6 +22,3 @@ structure ServiceError {
@required
message: String
}

View File

@ -5,46 +5,34 @@ namespace smithy.example
// In Smithy, example values of input structure members and the
// corresponding output or error structure members for an operation
// are grouped together into one set of example values for an operation.
apply GetCity @examples(
[
{
title: "Get City Example",
documentation: "Gets a city with the ID 1234",
input: {
cityId: "1234"
},
output: {
name: "Seattle"
coordinates: {
latitude: 47.6,
longitude: 122.3
[
{
title: "Get City Example"
documentation: "Gets a city with the ID 1234"
input: {cityId: "1234"}
output: {
name: "Seattle"
coordinates: {latitude: 47.6, longitude: 122.3}
}
},
}
]
}
]
)
apply CreateCity @examples(
[
{
title: "Create City Example",
documentation: "An example that creates a City Called Seattle",
input: {
name: "Seattle"
coordinates: {
latitude: 47.6,
longitude: 122.3
[
{
title: "Create City Example"
documentation: "An example that creates a City Called Seattle"
input: {
name: "Seattle"
coordinates: {latitude: 47.6, longitude: 122.3}
}
},
output: {
cityId: "1234"
name: "Seattle"
coordinates: {
latitude: 47.6,
longitude: 122.3
output: {
cityId: "1234"
name: "Seattle"
coordinates: {latitude: 47.6, longitude: 122.3}
}
},
}
]
)
}
]
)

View File

@ -3,19 +3,15 @@ $version: "2.0"
namespace smithy.example
apply GetForecast @examples(
[
{
title: "Create City Example",
documentation: "An example that creates a City Called Seattle",
input: {
cityId: "1234"
},
output: {
rating: "SOMEWHAT_HAPPY",
forecast: {
"rain": 12.0
[
{
title: "Create City Example"
documentation: "An example that creates a City Called Seattle"
input: {cityId: "1234"}
output: {
rating: "SOMEWHAT_HAPPY"
forecast: {rain: 12.0}
}
},
}
]
)
}
]
)

View File

@ -3,44 +3,37 @@ $version: "2.0"
namespace smithy.example
resource Forecast {
identifiers: { cityId: CityId },
read: GetForecast,
identifiers: {cityId: CityId}
read: GetForecast
}
@readonly
operation GetForecast {
input: GetForecastInput
output: GetForecastOutput
}
input := for Forecast {
@required
@httpLabel
$cityId
}
// "cityId" provides the only identifier for the resource since
// a Forecast doesn't have its own.
@input
structure GetForecastInput for Forecast{
@required
@httpLabel
$cityId
}
@output
structure GetForecastOutput {
rating: Rating
forecast: ForecastResult
output := {
rating: Rating
forecast: ForecastResult
}
}
/// How happy do we expect this forecast to make you
enum Rating {
SUPER_HAPPY,
SOMEWHAT_HAPPY,
MEH,
NOT_SO_HAPPY,
SUPER_HAPPY
SOMEWHAT_HAPPY
MEH
NOT_SO_HAPPY
UNHAPPY
}
// Unions represent a `one-of` relationship. The forecast could be
// either `rain` with a float value or `sun` with an integer value
union ForecastResult {
rain: ChanceOfRain,
rain: ChanceOfRain
sun: UVIndex
}

View File

@ -1,16 +1,15 @@
$version: "2.0"
metadata authors = [ "Bob", "Alice"]
metadata authors = ["Bob", "Alice"]
metadata company = "Examples R Us"
metadata license = "MYLICENSE 4.0"
metadata foo = "bar"
metadata validators = [
{
name: "EmitEachSelector"
id: "OperationInputName"
message: "This shape is referenced as input but the name does not end with 'Input'"
configuration: {
selector: "operation -[input]-> :not([id|name$=Input i])"
}
configuration: {selector: "operation -[input]-> :not([id|name$=Input i])"}
}
]

View File

@ -3,12 +3,11 @@ $version: "2.0"
namespace smithy.example
/// Provides weather forecasts
@paginated(inputToken: "nextToken", outputToken: "nextToken",
pageSize: "pageSize")
@paginated(inputToken: "nextToken", outputToken: "nextToken", pageSize: "pageSize")
@title("Weather Service")
service Weather {
version: "2006-03-01",
resources: [City],
version: "2006-03-01"
resources: [City]
operations: [GetCurrentTime]
// Add common errors that could be thrown by any route in the service
errors: [ServiceError, ThrottlingError]
@ -16,13 +15,8 @@ service Weather {
@readonly
operation GetCurrentTime {
output: GetCurrentTimeOutput
output := {
@required
time: Timestamp
}
}
structure GetCurrentTimeOutput {
@required
time: Timestamp
}

View File

@ -225,6 +225,9 @@
"smithy.api#required": {}
}
}
},
"traits": {
"smithy.api#output": {}
}
},
"smithy.example#GetCurrentTime": {
@ -248,6 +251,9 @@
"smithy.api#required": {}
}
}
},
"traits": {
"smithy.api#output": {}
}
},
"smithy.example#GetForecast": {
@ -428,4 +434,4 @@
}
}
}
}
}

View File

@ -138,7 +138,7 @@
"example.weather#GetCurrentTime": {
"type": "operation",
"input": {
"target": "example.weather#GetCurrentTimeInput"
"target": "smithy.api#Unit"
},
"output": {
"target": "example.weather#GetCurrentTimeOutput"
@ -147,13 +147,6 @@
"smithy.api#readonly": {}
}
},
"example.weather#GetCurrentTimeInput": {
"type": "structure",
"members": {},
"traits": {
"smithy.api#input": {}
}
},
"example.weather#GetCurrentTimeOutput": {
"type": "structure",
"members": {

View File

@ -1,12 +1,9 @@
$version: "2"
namespace example.weather
/// Provides weather forecasts.
@paginated(
inputToken: "nextToken"
outputToken: "nextToken"
pageSize: "pageSize"
)
@paginated(inputToken: "nextToken", outputToken: "nextToken", pageSize: "pageSize")
service Weather {
version: "2006-03-01"
resources: [City]
@ -14,15 +11,15 @@ service Weather {
}
resource City {
identifiers: { cityId: CityId }
identifiers: {cityId: CityId}
read: GetCity
list: ListCities
resources: [Forecast]
}
resource Forecast {
identifiers: { cityId: CityId }
read: GetForecast,
identifiers: {cityId: CityId}
read: GetForecast
}
// "pattern" is a trait.
@ -31,28 +28,26 @@ string CityId
@readonly
operation GetCity {
input: GetCityInput
output: GetCityOutput
errors: [NoSuchResource]
}
input := for City {
// "cityId" provides the identifier for the resource and
// has to be marked as required.
@required
$cityId
}
@input
structure GetCityInput {
// "cityId" provides the identifier for the resource and
// has to be marked as required.
@required
cityId: CityId
}
output := {
// "required" is used on output to indicate if the service
// will always provide a value for the member.
@required
name: String
@output
structure GetCityOutput {
// "required" is used on output to indicate if the service
// will always provide a value for the member.
@required
name: String
@required
coordinates: CityCoordinates
}
@required
coordinates: CityCoordinates
errors: [
NoSuchResource
]
}
// This structure is nested within GetCityOutput.
@ -77,22 +72,17 @@ structure NoSuchResource {
@readonly
@paginated(items: "items")
operation ListCities {
input: ListCitiesInput
output: ListCitiesOutput
}
input := {
nextToken: String
pageSize: Integer
}
@input
structure ListCitiesInput {
nextToken: String
pageSize: Integer
}
output := {
nextToken: String
@output
structure ListCitiesOutput {
nextToken: String
@required
items: CitySummaries
@required
items: CitySummaries
}
}
// CitySummaries is a list of CitySummary structures.
@ -101,7 +91,11 @@ list CitySummaries {
}
// CitySummary contains a reference to a City.
@references([{resource: City}])
@references(
[
{resource: City}
]
)
structure CitySummary {
@required
cityId: CityId
@ -112,34 +106,22 @@ structure CitySummary {
@readonly
operation GetCurrentTime {
input: GetCurrentTimeInput
output: GetCurrentTimeOutput
}
@input
structure GetCurrentTimeInput {}
@output
structure GetCurrentTimeOutput {
@required
time: Timestamp
output := {
@required
time: Timestamp
}
}
@readonly
operation GetForecast {
input: GetForecastInput
output: GetForecastOutput
}
input := for Forecast {
// "cityId" provides the only identifier for the resource since
// a Forecast doesn't have its own.
@required
$cityId
}
// "cityId" provides the only identifier for the resource since
// a Forecast doesn't have its own.
@input
structure GetForecastInput {
@required
cityId: CityId
output := {
chanceOfRain: Float
}
}
@output
structure GetForecastOutput {
chanceOfRain: Float
}

View File

@ -1,12 +1,9 @@
$version: "2"
namespace example.weather
/// Provides weather forecasts.
@paginated(
inputToken: "nextToken"
outputToken: "nextToken"
pageSize: "pageSize"
)
@paginated(inputToken: "nextToken", outputToken: "nextToken", pageSize: "pageSize")
service Weather {
version: "2006-03-01"
resources: [City]
@ -14,15 +11,15 @@ service Weather {
}
resource City {
identifiers: { cityId: CityId }
identifiers: {cityId: CityId}
read: GetCity
list: ListCities
resources: [Forecast]
}
resource Forecast {
identifiers: { cityId: CityId }
read: GetForecast,
identifiers: {cityId: CityId}
read: GetForecast
}
// "pattern" is a trait.
@ -31,28 +28,26 @@ string CityId
@readonly
operation GetCity {
input: GetCityInput
output: GetCityOutput
errors: [NoSuchResource]
}
input := for City {
// "cityId" provides the identifier for the resource and
// has to be marked as required.
@required
$cityId
}
@input
structure GetCityInput {
// "cityId" provides the identifier for the resource and
// has to be marked as required.
@required
cityId: CityId
}
output := {
// "required" is used on output to indicate if the service
// will always provide a value for the member.
@required
name: String
@output
structure GetCityOutput {
// "required" is used on output to indicate if the service
// will always provide a value for the member.
@required
name: String
@required
coordinates: CityCoordinates
}
@required
coordinates: CityCoordinates
errors: [
NoSuchResource
]
}
// This structure is nested within GetCityOutput.
@ -77,22 +72,17 @@ structure NoSuchResource {
@readonly
@paginated(items: "items")
operation ListCities {
input: ListCitiesInput
output: ListCitiesOutput
}
input := {
nextToken: String
pageSize: Integer
}
@input
structure ListCitiesInput {
nextToken: String
pageSize: Integer
}
output := {
nextToken: String
@output
structure ListCitiesOutput {
nextToken: String
@required
items: CitySummaries
@required
items: CitySummaries
}
}
// CitySummaries is a list of CitySummary structures.
@ -101,7 +91,11 @@ list CitySummaries {
}
// CitySummary contains a reference to a City.
@references([{resource: City}])
@references(
[
{resource: City}
]
)
structure CitySummary {
@required
cityId: CityId
@ -112,34 +106,22 @@ structure CitySummary {
@readonly
operation GetCurrentTime {
input: GetCurrentTimeInput
output: GetCurrentTimeOutput
}
@input
structure GetCurrentTimeInput {}
@output
structure GetCurrentTimeOutput {
@required
time: Timestamp
output := {
@required
time: Timestamp
}
}
@readonly
operation GetForecast {
input: GetForecastInput
output: GetForecastOutput
}
input := for Forecast {
// "cityId" provides the only identifier for the resource since
// a Forecast doesn't have its own.
@required
$cityId
}
// "cityId" provides the only identifier for the resource since
// a Forecast doesn't have its own.
@input
structure GetForecastInput {
@required
cityId: CityId
output := {
chanceOfRain: Float
}
}
@output
structure GetForecastOutput {
chanceOfRain: Float
}