Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Best practices guide on extending the server #2777

Open
hlbarber opened this issue Jun 14, 2023 · 0 comments
Open

Best practices guide on extending the server #2777

hlbarber opened this issue Jun 14, 2023 · 0 comments
Labels
documentation Improvements or additions to documentation server Rust server SDK

Comments

@hlbarber
Copy link
Contributor

hlbarber commented Jun 14, 2023

Extending the code generator is non-trivial and undocumented.

This issue attempts to outline a standard approach for third parties to extend the code generator. This outline should be fleshed out in a extension.md server section of the book.

Consider the common scenario:

I, as a third-party, am interested in implementing code generation for a trait which is not supported via vanilla smithy-rs. The trait adds some additional semantics the shapes defined in the model.

  1. Define a Rust trait, in a third party crate, which acts as an interface to the Smithy traits desired effects. For example, if we had a @log trait which identified a field which should be logged per request then the interface might look like
trait Log {
    fn log(&self, writer: &mut dyn Write) ;
}
  1. Extend the code generator to implement the Log trait when @log is present. This should be an addition to the server SDK and be easy for us to provide the extension points. Each Smithy shape has an associated Rust struct so we have a consistent surface to do this over.
  2. In the third party crate, define a Plugin which assumes the existence of these traits.
impl Service<Input> for LogService
where
    Input: Log
{
     async fn call(&mut self, request: Input) -> Result<Self::Response, Self::Error> {
        request.log(&mut Stdout::lock());
        self.inner.call(request).await
    }
}

impl Plugin<Ser, Op, S> for LogPlugin
{
    type Service = LogService<S>;

    /* ... */
}
  1. Extend the service config to apply the LogPlugin, adding methods to configure it when needed.

Each of these steps is designed to be non-invasive and robust to internal changes. This approach attempts to minimize the amount of Kotlin required, relying on the more stable Rust interfaces. The third party will maintain one Rust crate, containing the semantics and business logic, and one Kotlin package which extracts information from the Smithy model and presents it via the trait Log implementation.

@hlbarber hlbarber added documentation Improvements or additions to documentation server Rust server SDK labels Jun 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation server Rust server SDK
Projects
None yet
Development

No branches or pull requests

1 participant