Skip to content

Server's build and build_unchecked apply layers from the generated config object in a different order #3605

@david-perez

Description

@david-perez

build() returns:

pub fn build(self) -> Result<
    PokemonService<
        ::aws_smithy_http_server::routing::RoutingService<
            ::aws_smithy_http_server::protocol::rest::router::RestRouter<L::Service>,
            ::aws_smithy_http_server::protocol::rest_json_1::RestJson1,
        >,
    >,
    MissingOperationsError,
>
where
    L: ::tower::Layer<::aws_smithy_http_server::routing::Route<Body>>,
{
    ...
    let svc = ::aws_smithy_http_server::routing::RoutingService::new(router);
    let svc = svc.map(|s| s.layer(self.layer));
    Ok(PokemonService { svc })
}

So the .layers registered in config will run in B position after routing.

On the other hand, build_unchecked() returns:

pub fn build_unchecked(self) -> PokemonService<L::Service>
where
    Body: Send + 'static,
    L: ::tower::Layer<
        ::aws_smithy_http_server::routing::RoutingService<::aws_smithy_http_server::protocol::rest::router::RestRouter<::aws_smithy_http_server::routing::Route<Body>>, ::aws_smithy_http_server::protocol::rest_json_1::RestJson1>
    >
{
    ...
    let svc = self
     .layer
     .layer(::aws_smithy_http_server::routing::RoutingService::new(router));
    PokemonService { svc }
}

So the .layers run in A position, before routing.

The correct behavior is build's. We introduced the config object as a nice way to register middleware within routing; users can always register middleware in A position by wrapping the built Service with tower::Layers as they'd do with any other Service.

When fixing this:

  • document in the Rust docs for the generated config object that layers get run in B position, HTTP plugins in C position, and model plugins in D position.
    • Call out how to add a layer in A position.
  • add a test to our example Pokemon service that ensures that middleware gets invoked in ABCD order regardless of whether we use build or build_unchecked.

Metadata

Metadata

Assignees

No one assigned

    Labels

    breaking-changeThis will require a breaking changebugSomething isn't workingserverRust server SDK

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions