How does Taxi and its goals compare to that of Smithy? https://awslabs.github.io/smithy/

On the surface it looks like they're attempting to solve very similar problems. Smithy also seems to come with code generators that can produce client libraries in various languages for calling the APIs too -- something that would be an important feature to me. There are implementations for a number of languages apparently, at various stages of maturity: https://awslabs.github.io/smithy/implementations.html

Among them include TypeScript, Go, Rust, Kotlin, Swift, Scala; server -side generators for TypeScript; and model converters for converting Smithy models to Open API or JSON Schema (presumably where compatible).

Cool project. I've definitely hoped that a toolkit would become de facto standard that provides model definition, protocol bindings (abstract operations accepting/returning models aka resources, described as a specific wire protocol like HTTP), and finally code generation for both client and server-sides of the interface for multiple platforms.

It looks like Smithy encourages the same approach of defining unique types to represent model fields. A Smithy example pulled from their page (abbreviating some newlines since HN still doesn't support Markdown :-( for code blocks):

// "pattern" is a trait.
@pattern("^[A-Za-z0-9 ]+$")
string CityId

resource City {
identifiers: { cityId: CityId },
read: GetCity,
list: ListCities,
resources: [Forecast],
}

resource Forecast {
identifiers: { cityId: CityId },
read: GetForecast,
}

@readonly
operation GetCity {
input: GetCityInput,
output: GetCityOutput,
errors: [NoSuchResource]
}

@input
structure GetCityInput {
// "cityId" provides the identifier for the resource and
// has to be marked as required.
@required
cityId: CityId
}

Where existing RPC toolkits like Apache Thrift, gRPC, and Cap'n Proto define and derive their wire formats from your IDL, and you have no control over them, I like this concept's power because you can:

(1) use it to match and model the interface of an existing API, if you need to

(2) generate client and server stubs for many platforms, saving the hassle of trying to integrate with raw HTTP APIs (frequently mistermed "REST")

(3) ideally the toolkit would also provide bindings or plugins for multiple potential protocols, such as an HTTP resource-oriented representation, or a binary BSON representation, etc., to allow for easily making tradeoffs between APIs that are human-accessible and those that are more highly efficient (although if you can count on HTTP/2 or HTTP/3 at all layers, regular "text" requests should actually be quite efficient). And if you don't need the API to be easily callable from browse JavaScript, all the substantial parameters could be represented by HTTP headers to benefit from those protocols' header compression.

(4) Perhaps a plugin could also provide a special-purpose (perhaps configuration-driven, but might require the ability to define state machines; perhaps the protocol translator could be implemented in one language as a sort of VM with a sequence of commands for how the service API, and its operations, models, resources, types are converted into binary wire format.

(5) Toolkits like this if designed with foresight could also be useful for modeling (large) data sets -- a completely different use-case than providing APIs. For example, a plugin to convert collections of models/resources into Apache Parque and back, or other similar efficient bulk data formats. You could the toolkit to model your system's log file format (where resource collections convert to newline-delimited JSON text files), or perhaps performance.

Anywhere that data is handled, it ought to have a formal model in my opinion. Toolkits like these will simplify translating and manipulating it between formats and systems in a type-safe way given sufficient code generation support. (For example, in languages that support opaque type aliases, CityId, despite being a string, would not be castable to/from string.

Instead, a transformation can be defined to convert a CityId to string if necessary -- otherwise, developers are discouraged from conflating many types that might be aliases for string as interchangeable, permitting errors that a strong type system with opaque aliases would catch. (For example, since a CityId must match a regex, creating one would require calling a function that perhaps accepts a string as input, validates the regex, and then returns a CityId as long as the regex matches.) It's interesting to imagine what other semantic validation could be lifted up to the model level to make applications more robust. Perhaps the next stage beyond this one might be relationships between data. For example, perhaps a model could include a set of words, and then a text blob that must consist exclusively of space-delimited words from that list; or a list of banned words.

Anyway, it looks like Taxi and Smithy might be close enough in goals to potentially benefit from exploring collaboration. On the other hand some competition might be healthy.