Skip to main content

aws_smithy_http_server/
service.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6//! The shape of a [Smithy service] is modelled by the [`ServiceShape`] trait. Its associated types
7//! [`ServiceShape::ID`], [`ServiceShape::VERSION`], [`ServiceShape::Protocol`], and [`ServiceShape::Operations`] map
8//! to the services [Shape ID](https://smithy.io/2.0/spec/model.html#shape-id), the version field, the applied
9//! [protocol trait](https://smithy.io/2.0/aws/protocols/index.html) (see [`protocol`](crate::protocol) module), and the
10//! operations field.
11//!
12//! We generate an implementation on this for every service struct (exported from the root of the generated crate).
13//!
14//! Schema-generated services also implement [`SchemaServiceShape`], connecting the typed service to its
15//! shared [`ServiceSchema`](crate::schema::ServiceSchema) descriptor.
16//!
17//! As stated in the [operation module documentation](crate::operation) we also generate marker structs for
18//! [`OperationShape`](crate::operation::OperationShape), these are coupled to the `S: ServiceShape` via the [`ContainsOperation`] trait.
19//!
20//! The model
21//!
22//! ```smithy
23//! @restJson1
24//! service Shopping {
25//!     version: "1.0",
26//!     operations: [
27//!         GetShopping,
28//!         PutShopping
29//!     ]
30//! }
31//! ```
32//!
33//! is identified with the implementation
34//!
35//! ```rust,no_run
36//! # use aws_smithy_http_server::shape_id::ShapeId;
37//! # use aws_smithy_http_server::service::{ServiceShape, ContainsOperation};
38//! # use aws_smithy_http_server::protocol::rest_json_1::RestJson1;
39//! # pub struct Shopping;
40//! // For more information on these marker structs see `OperationShape`
41//! struct GetShopping;
42//! struct PutShopping;
43//!
44//! // This is a generated enumeration of all operations.
45//! #[derive(PartialEq, Eq, Clone, Copy)]
46//! pub enum Operation {
47//!     GetShopping,
48//!     PutShopping
49//! }
50//!
51//! impl ServiceShape for Shopping {
52//!     const ID: ShapeId = ShapeId::new("namespace#Shopping", "namespace", "Shopping");
53//!     const VERSION: Option<&'static str> = Some("1.0");
54//!     type Protocol = RestJson1;
55//!     type Operations = Operation;
56//! }
57//!
58//! impl ContainsOperation<GetShopping> for Shopping {
59//!     const VALUE: Operation = Operation::GetShopping;
60//! }
61//!
62//! impl ContainsOperation<PutShopping> for Shopping {
63//!     const VALUE: Operation = Operation::PutShopping;
64//! }
65//! ```
66//!
67//! [Smithy service]: https://smithy.io/2.0/spec/service-types.html#service
68
69use crate::shape_id::ShapeId;
70
71/// Models the [Smithy Service shape].
72///
73/// [Smithy Service shape]: https://smithy.io/2.0/spec/service-types.html#service
74pub trait ServiceShape {
75    /// The [`ShapeId`] of the service.
76    const ID: ShapeId;
77
78    /// The version of the service.
79    const VERSION: Option<&'static str>;
80
81    /// The [Protocol] applied to this service.
82    ///
83    /// [Protocol]: https://smithy.io/2.0/spec/protocol-traits.html
84    type Protocol;
85
86    /// An enumeration of all operations contained in this service.
87    type Operations;
88}
89
90/// Connects a typed service to its shared schema descriptor.
91///
92/// Schema-generated services implement this trait in addition to [`ServiceShape`].
93/// The descriptor contains the service's identity, version, protocols, and operation schemas.
94pub trait SchemaServiceShape: ServiceShape {
95    /// The shared descriptor for this service.
96    const SCHEMA: &'static crate::schema::ServiceSchema<'static>;
97}
98
99pub trait ContainsOperation<Op>: ServiceShape {
100    const VALUE: Self::Operations;
101}
102
103/// Names the error-conversion strategy of a generated service.
104///
105/// Every generated service implements this trait. [`SerdeKind`](Self::SerdeKind) is
106/// [`GeneratedSerde<Protocol>`](crate::response::GeneratedSerde) for generated-serde services,
107/// whose errors implement context-free [`IntoResponse`](crate::response::IntoResponse) for the
108/// statically known protocol, and [`SchemaSerde`](crate::response::SchemaSerde) for schema-serde
109/// services, whose errors are serialized by the protocol routing selected per request.
110///
111/// Middleware generic over the service bounds `Ser: ServiceSerde` and uses `Ser::SerdeKind` as an
112/// [`ErrorConverter`](crate::response::ErrorConverter) to turn operation errors into HTTP
113/// responses without a serde-mode parameter on the plugin.
114pub trait ServiceSerde {
115    /// Marker type implementing [`ErrorConverter`](crate::response::ErrorConverter) for this
116    /// service's error types.
117    type SerdeKind;
118}