smithy-lang / smithy

Smithy is a protocol-agnostic interface definition language and set of tools for generating clients, servers, and documentation for any programming language.

Home Page:https://smithy.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

HTTP binding traits mistakenly allowed in RPC protocols

david-perez opened this issue · comments

In RPC protocols like AWS JSON and RPC v2 CBOR, HTTP binding traits are currently allowed. For example, this model builds fine:

@rpcv2Cbor
service RpcV2Service {
    operations: [
        SimpleStructOperation,
    ]
}

// `@http` trait has no effect
@http(uri: "/simple-struct-operation", method: "POST")
operation SimpleStructOperation {
    input: SimpleStruct
    output: SimpleStruct
}

I think Smithy should disallow these traits if in all the protocols the service supports they are meaningless.

Services can have multiple protocols, each of which may or may not respect certain traits, so we can't reasonably fail a build in those cases.

I know, but can't we fail the build/emit a warning in the case where in all the protocols the service supports the traits are meaningless, like in the example I provided?

I think that would be confusing for cases where a shared definition of an operation is used by an RPC based service. The shared operation definition (e.g., TagResource) might define HTTP bindings in order to make it just work if the service uses HTTP bindings, and services that don't would ignore the bindings.

HTTP binding traits are usually applied to top-level inputs/outputs and most only have an effect when applied there. I'm not sure how common the use case of re-using these shapes across services with disjoint protocols is, but I haven't seen it. On the other hand, so far I've seen 2 internal users being confused about why their HTTP binding traits had no effect on their RPC services.

It also makes the implementation of each code generator more complex: they need to support only the traits specified by the protocol's specification (example) and intentionally ignore the others. What traits a protocol supports seems like a protocol-centric responsibility, it would be nice if Smithy could vend model transformers such that all traits that have no semantics in the selected protocols are stripped out. This complexity has caused at least one code generation bug in smithy-rs.

It’s quite common. Even framework and synthetic errors when we finish them will apply HTTP traits that could be ignored based on the protocol.

Protocol definition traits list which traits they support in the trait definition in the model. You could use that to strip out traits if needed. I think a better long term solution is that generators support multiple simultaneous protocols and not stripping protocol traits, so I don’t think a built-in transform is the right direction.