This looks pretty sweet; I've spent a lot of time the past few years writing a LOT of OpenAPI specifications and the thing that gets tiring is all of the boilerplate with each bit of the definition (paths -> get -> responses -> 200 -> application/json -> schema). It gets so exhausting and turns into nested YAML soup pretty quickly. Having better support for multiple files will also be nice; _technically_ you can split an OpenAPI specification into multiple files but the tooling never quite deals with it properly.
I'll definitely be keeping an eye on this; looking forward to TypeScript code generation! One of our main use cases for OpenAPI is to document our models and then generate TypeScript types from them (that we then use in Node and React apps)
Ive used a bit of smithy at work. Yes, composable models, projections, and transforms are super common. Think joining multiple microservices in to a single public interface or splitting out different service/client models based on tags or traits. Most of this is handled by build infrastructure so it takes some mental energy to setup but then it “just works.”
Hey TranquilMarmot. I am working on a TypeScript code Generator for OpenAPI 2 and 3 that you might be interested in. It works on Node.js and web, provides strong typing (types generated against schema in the OpenAPI definition) and runtime type-checking to prevent the runtime data from deviating from TS types. We have been testing it in private for sometime; clients generated using this Code Generator have already been installed ~50K (and counting). I am looking for feedback so I'd be happy if you could try it out. My email is in my profile.
We were bothered by the same thing :) Many plugins for OpenAPI had no codegens which would produce deterministic behavior for compatibility across various languages. Also we wanted to have something that could express complex business domains in definitions.
Ended up building protoforce.io for the very purpose. It does support typescript + nodejs, which we used for the website itself as well.
We use multiple files at work, but all of our make rules first bundle the spec into a single file. We also save that bundle in our VCS. CI will fail if the bundle hasn't been recreated since updating the split files
We've built a similar thing at https://www.protoforce.io, which auto-generates client and server side. It actually transpiles, parsing the models definitions and emits actual code with a bit of shared runtime.
Good amazon opened up their stuff, there should be more competition on this front.
This is some impressive stuff! Congrats on a sizable achievement. I just went through your website, have a few questions...
Questions:
1. SCALA: is the generated code ONLY scala? are other languages supported?
2. CODE-GEN: is it designed only for code generation for a target http framework or does it actually provide an "API Server" itself ( e.g. like graphQL )
3. COMPARISON: the list of frustrations with other solutions, listed in your intro/technology goals are somewhat high-level. what are the "leaky abstractions" or "non-deterministic behaviour"?
4. SETUP: does someone need to know scala to use this ? ( depends on #1 above )
5. DSL : is the protoforce code implemented as a DSL in Scala or its a "language" in itself?
6. IDE : how do you check/compile the code? does it integrated with an IDE?
As a Scala Engineer myself ( though I mostly work in Kotlin now for Android/Server ), this looks great, but most Scala engineers i've met are focused on Spark, and using Play Framework/Http4S, etc. How big is the actual market for Scala API tools?
3. Please take a look at the documentation, it has a good outline of the features supported. There are many features, most are well documented there.
4. No, not really. You can do with other languages, it provides both client & server sides, so no other language is needed. Again, you can still generate client side stuff for other languages and use them to connect to your server.
5. protoforce website was implemented using the protoforce DSL itself. The parser and transpilers are written in scala. The portal is written in typescript + react.
6. There is currently a sandbox at the website which you can experiment in. There is no currently integration with other IDEs, but language server can be added a bit later for VSCode for instance.
I think it's a really powerful paradigm. I think an org adopting such patterns widespread leads to some really rad capabilities. GDPR compliance, for example, is really tough in SOA architectures in companies without a ton of engineering capacity, but this sort of data/api introspection could do a lot to change that.
Any plans to open source projection for languages other than Java?
edit: I see that typescript and rust are available on github as well
This is great. I'm happy to see more evolution in the service definition space, especially in using custom DSL's. The low signal-to-noise ratio and boilerplate in OpenAPI and RAML is a killer IMO.
We're building something similar with Taxi (https://docs.taxilang.org), which provides a rich way to describe services and data.
Similar to Smithy's CityId example, we provide the ability to semantically describe attributes. Our product - Vyne (https://vyne.co) can then use these Id's to automatically chain and orchestrate any services together, without having to write integration code.
I gotta say this is really neat. Definitely going to take it for a spin. I’ve always felt like a lot of these tools have too much ceremony - this feels light and simple.
Protobuf is commonly used to refer to both the serialization format and the IDL. You can use protos to specify JSON/REST endpoints. In past companies I've also used it to specify DB schemas.
> while Smithy is just an idl used to describe services
What's the use of such descriptions aside from diagrams? I realize there's e.g. terraform that use similar kind of language to describe what to create/destroy.
Protobuf and gRPC are great, and AWS will continue to make sure developers can be successful using them with AWS. I’ll try to explain how we ended up at Smithy instead of using other existing tools.
We started working on Smithy around 2018 because we wanted to improve the scale of our API program and the AWS SDK team to deal with the growing number of services (over 250 now!) and languages we want to support in official AWS SDKs (like the newly released Rust SDK). We had a ton of existing services that we needed to be compatible with, but we also wanted to add new features to improve new services going forward too.
We needed a very flexible meta-model that allows us to continue to evolve the model to account for things like integrating with other systems and to model service-specific customizations that each AWS SDK team can implement independently. Smithy's meta-model is based on traits, a self-describing way to add more information to models. Lots of validation can be built in to custom traits, which helps to ensure that service teams are using traits properly and adhere to their specifications. Smithy's resource modeling helps us here too because it allows AWS service teams, as they adopt Smithy, to essentially automatically support CloudFormation resource schemas. Resources also help us to point service teams in the right direction to make their services work well over HTTP (which methods to use, URIs, safety, idempotency, etc).
We needed an integrated model validation, linting, and diff tool to keep services consistent and detect breaking changes, and it needed to support company-wide standards as well as service-specific standards. We use Smithy’s validation system to automatically enforce API standards, and service teams often create their own service-specific rules to keep their own internal consistency.
We needed built-in input validation constraints so that they're standard across services and clients (e.g., length, range, pattern, etc). We didn't want to rely on third-party extensions to provide this feature since validating inputs is important. AWS uses internal service frameworks that enforce these constraints and are compatible with Smithy models. We're working to create open source service frameworks for Smithy as well.
We also wanted to support various serialization formats so that clients work with all of our existing services spread across JSON, XML, query strings, RPC, and HTTP APIs, but we also wanted to be able to evolve our serialization formats in the future as new technology comes along. That's why Smithy is protocol agnostic (like gRPC actually). The serialization format is an implementation detail. Smithy has some support for MQTT as well.
And finally, we need our code generators to be really flexible to support service customizations. There's quite a few customizations across AWS services, and we needed a way to inject custom code generation logic in various parts of our generators.
Smithy is still in heavy development, and we're working on building out more of the tooling so it can be used easily outside of AWS SDKs too, including client and server code generation.
Thanks for the thorough response! This helps me understand the motivations behind Smithy. I’m going to dig into the project and keep an eye on it as the tooling develops.
> Smithy's resource modeling helps us here too because it allows AWS service teams, as they adopt Smithy, to essentially automatically support CloudFormation resource schemas.
well, what is it? What was autogenerated? I know JAVA from previous jobs, but not Gradle and whatever the Smithy generated artifacts are to be composed with is unclear to me.
It's not really a fully finished project yet, so not much. We shipped the AWS SDK for JS v3 with Smithy, the AWS SDK for Go v2 with Smithy, and just launched an alpha of the AWS SDK for Rust using Smithy. More are in the works. We're currently iterating on their code generators to make them easier to use outside the AWS SDKs. AWS SDKs are being built in a layered approach where there's a generic code generator that's really extensible, and then the AWS SDKs extend it to add AWS-specific stuff like regions and credential handling.
I gather the impact of Smithy is to generate something like an old style CORBA client/server stubs and vocabulary types for a given serialization, and communication schema (HTTP2, gRPC) in a target language? Is Smithy specific to interoperating with AWS services or can used in pretty much any distributed system?
I'll definitely be keeping an eye on this; looking forward to TypeScript code generation! One of our main use cases for OpenAPI is to document our models and then generate TypeScript types from them (that we then use in Node and React apps)
Note: Principal at AWS.
Ended up building protoforce.io for the very purpose. It does support typescript + nodejs, which we used for the website itself as well.
Dead Comment
Good amazon opened up their stuff, there should be more competition on this front.
Questions:
1. SCALA: is the generated code ONLY scala? are other languages supported?
2. CODE-GEN: is it designed only for code generation for a target http framework or does it actually provide an "API Server" itself ( e.g. like graphQL )
3. COMPARISON: the list of frustrations with other solutions, listed in your intro/technology goals are somewhat high-level. what are the "leaky abstractions" or "non-deterministic behaviour"?
4. SETUP: does someone need to know scala to use this ? ( depends on #1 above )
5. DSL : is the protoforce code implemented as a DSL in Scala or its a "language" in itself?
6. IDE : how do you check/compile the code? does it integrated with an IDE?
As a Scala Engineer myself ( though I mostly work in Kotlin now for Android/Server ), this looks great, but most Scala engineers i've met are focused on Spark, and using Play Framework/Http4S, etc. How big is the actual market for Scala API tools?
1. Scala, Typescript/Javascript, and Java at the moment.
2. It does provide the runtime which allows to bootstrap a server easily. (You can check out this post which has modeling + scala setup example at the bottom https://www.protoforce.io/ProtoForce/post/extensive-guide-to...)
3. Please take a look at the documentation, it has a good outline of the features supported. There are many features, most are well documented there.
4. No, not really. You can do with other languages, it provides both client & server sides, so no other language is needed. Again, you can still generate client side stuff for other languages and use them to connect to your server.
5. protoforce website was implemented using the protoforce DSL itself. The parser and transpilers are written in scala. The portal is written in typescript + react.
6. There is currently a sandbox at the website which you can experiment in. There is no currently integration with other IDEs, but language server can be added a bit later for VSCode for instance.
Hope this answers a bit :)
Dead Comment
I think it's a really powerful paradigm. I think an org adopting such patterns widespread leads to some really rad capabilities. GDPR compliance, for example, is really tough in SOA architectures in companies without a ton of engineering capacity, but this sort of data/api introspection could do a lot to change that.
Any plans to open source projection for languages other than Java?
edit: I see that typescript and rust are available on github as well
[0]: https://news.ycombinator.com/item?id=27080859
We're building something similar with Taxi (https://docs.taxilang.org), which provides a rich way to describe services and data.
Similar to Smithy's CityId example, we provide the ability to semantically describe attributes. Our product - Vyne (https://vyne.co) can then use these Id's to automatically chain and orchestrate any services together, without having to write integration code.
[0] https://developers.google.com/protocol-buffers
The services are free to serialize the data in any way be it json, XML or even protocol buffers.
So Smithy is more comparable to OpenApi than Protocal buffers.
What's the use of such descriptions aside from diagrams? I realize there's e.g. terraform that use similar kind of language to describe what to create/destroy.
We started working on Smithy around 2018 because we wanted to improve the scale of our API program and the AWS SDK team to deal with the growing number of services (over 250 now!) and languages we want to support in official AWS SDKs (like the newly released Rust SDK). We had a ton of existing services that we needed to be compatible with, but we also wanted to add new features to improve new services going forward too.
We needed a very flexible meta-model that allows us to continue to evolve the model to account for things like integrating with other systems and to model service-specific customizations that each AWS SDK team can implement independently. Smithy's meta-model is based on traits, a self-describing way to add more information to models. Lots of validation can be built in to custom traits, which helps to ensure that service teams are using traits properly and adhere to their specifications. Smithy's resource modeling helps us here too because it allows AWS service teams, as they adopt Smithy, to essentially automatically support CloudFormation resource schemas. Resources also help us to point service teams in the right direction to make their services work well over HTTP (which methods to use, URIs, safety, idempotency, etc).
We needed an integrated model validation, linting, and diff tool to keep services consistent and detect breaking changes, and it needed to support company-wide standards as well as service-specific standards. We use Smithy’s validation system to automatically enforce API standards, and service teams often create their own service-specific rules to keep their own internal consistency.
We needed built-in input validation constraints so that they're standard across services and clients (e.g., length, range, pattern, etc). We didn't want to rely on third-party extensions to provide this feature since validating inputs is important. AWS uses internal service frameworks that enforce these constraints and are compatible with Smithy models. We're working to create open source service frameworks for Smithy as well.
We also wanted to support various serialization formats so that clients work with all of our existing services spread across JSON, XML, query strings, RPC, and HTTP APIs, but we also wanted to be able to evolve our serialization formats in the future as new technology comes along. That's why Smithy is protocol agnostic (like gRPC actually). The serialization format is an implementation detail. Smithy has some support for MQTT as well.
And finally, we need our code generators to be really flexible to support service customizations. There's quite a few customizations across AWS services, and we needed a way to inject custom code generation logic in various parts of our generators.
Smithy is still in heavy development, and we're working on building out more of the tooling so it can be used easily outside of AWS SDKs too, including client and server code generation.
Hallelujah!
https://awslabs.github.io/smithy/quickstart.html#next-steps
well, what is it? What was autogenerated? I know JAVA from previous jobs, but not Gradle and whatever the Smithy generated artifacts are to be composed with is unclear to me.
We're working to get projects like these to GA: https://github.com/awslabs/smithy-typescript, https://github.com/aws/smithy-go, and https://github.com/awslabs/smithy-rs. And we're also working on service code generation.