Addition of a cats module to contain SchemaVisitor
implementations of commonly-used cats typeclasses. Currently included are cats.Show
and cats.Hash
(note that cats.Eq
is provided by the cats.Hash
implementation).
Allows for marking string types with the alloy#structurePattern
trait. This trait indicates that a given pattern, with parameters, applies to a given string and that this string should
actually be parsed into a structure where the members of the structure are derived from the parameters in the string pattern.
Allows creating implicit typeclass instances in the companion objects in the smithy4s-generated code. This is useful for creating instances of
typeclasses such as cats.Show
, cats.Eq
or any others you may be using.
This release is backward binary-compatible with the previous releases from the 0.17.x lineage. However, the generated code produced by this version is not entirely source-compatible with the previous version. More info below.
This version introduces changes in how the code is rendered that may result in some breakage in userland. We've carefully architected the changes to reduce the likelihood of breakage happening.
A number of constructs are now rendered not in the companion object of the generated service, but rather in the companion object of the reified operation type. These constructs include the error types that get generated by operations.
This change has been performed in order to eliminate the risk of collision between the generated types and some type
members present in the smithy4s.Service
interface. This collision, when it happened, was making the code impossible to
compile.
In order to reduce breakage around the error types (which are likely to be used in userland), we have decided to generate aliases at the location where they used to live. The generated code should not break source compatibility in the large majority of usage of Smithy4s.
A small minority of users may have to change how they access the generated constructs they may have depended on. This is unlikely, as the constructs in question are used internally by interpreters via interfaces that haven't changed, and they are not constructs that are advertised in our documentation. We only expect some possible breakage in advanced usage performed by a handful of people.
See:
Changed the handling of the httpQueryParams
(plural) trait so that possible httpQuery
-annotated fields do not take priority
over it during decoding. This means that httpQueryParams
receive the whole set of query parameters, which may induce duplication
with the value contained by overlapping httpQuery
-annotated fields.
On the encoding side, the behaviour is that httpQuery
fields have priority over httpQueryParams
fields.
This is a more faithful implementation of the spec.
Adds logic to validate the model after pre-processing model transformations (before the code-generation)
AWS has changed the Smithy specification of the DATE_TIME
timestamp format to precise that numeric offsets should be handled.
This is now the case.
The currently undocumented dynamic
module has received an improvement allowing to access the metadata
of the loaded models via its platform-agnostic interface.
Empty bodies are now correctly using the built-in withEmptyBody
of Http4s, which correctly removes
the Content-Type
header from the request upon usage. This solves issues when Smithy4s is being called
(or calling) strict clients/servers that check this type of thing.
The AWS Json protocols specify that NaN
, Infinity
and -Infinity
are valid values for Double
and Float
types.
This is now handled.
A bug was preventing dependencies that would have special characters in their absolute paths to be loaded successfully. This is now fixed.
Byte
fields are now correctly supported when used by an httpLabel
member.
This release is backward binary-compatible with the previous releases from the 0.17.x lineage.
This release is backward binary-compatible with the previous releases from the 0.17.x lineage.
Under certain conditions, it is now possible to annotate union shapes with @adt
, which has the effect of inlining
all the structure shapes under it directly in the companion object of the union, as opposed to create Case
-suffixed
wrappers. Additionally, when a union is annotated with @adt
, the intersection of mixin shapes that are applied to every member of the union is now used as Scala-level mixin traits. This facilitates object-oriented usage of Smithy4s.
Read the new docs for more info.
Smithy @documentation
traits (which has syntactic sugar in the form of triple-slashes-prefixed comments) is now used to generate Scaladoc above the relevant data-types, interfaces and methods that get generated in Smithy4s.
Thank you @zetashift for this awesome contribution and @msosnicki for this valuable contribution !
Under conditions which should automatically be propagated from the build-tool to the code-generation, Scala 3 wildcards now get generated instead of Scala 2 wildcards. This makes user experience better on Scala 3, as syntax deprecation warnings will no longer be issued.
Thank you @albertpchen for this awesome contribution !
It is now possible to directly instantiate AWS clients against a Monadic context, which makes for a better UX when calling unary request/response operations. When using that mode, stream operations being called such clients will fail with a raised exception.
It is now possible to load credentials from an AWS-compliant configuration file (typically found under ~/.aws/credentials). This is wired by default in the clients, and has lower precedence than the other providers.
We've improved and added new sections to the documentation, in particular around AWS SDK usage and model pre-processing.
The default trait allows for not setting a value. Now, the absence of value (ie null) in the default trait at the smithy level translates to the correct "zero" value of the target type.
Null documents were not being decoded as None
, but rather were leading to decoding failures
when decoding data types from smithy4s.Document
The URI was previously using the wrong relative path
Loading a smithy 1.0 model with smithy 2.0 tooling (which Smithy4s uses) leads to the automatic addition of "default" traits on some shapes and members. When combined with refinements, this had the side effect of treating the refined type as required when it should be in fact optional. It's all the more confusing that there is no mechanism in place to reconcile refinement logic, with default values, as refinement logic is expressed in run-time code whereas default value validation is expressed in build-time code.
Yet another awesome contribution from @plokhotnyuk to shave allocations off the Json parsing logic, leading to performance improvements.
Our implementation of our alloy#simpleRestJson
protocol is now derived automatically from test specifications
written in Smithy itself
See:
This also paves the road for testing our implementation of the AWS protocols using official tests, which are located [there]
Some tweaks were made to the smithy4s.Enumeration.Value
interface to allow for more generic logic using enumerations.
This release is backward binary-compatible with the previous releases from the 0.17.x lineage.
In order to render Operation errors as Scala 3 union types, a following metadata flag needs to be added: metadata smithy4sErrorsAsScala3Unions = true
(in any of the smithy files that are used for code generation).
This will make it easier to run front-end debuggers on webpage build with smithy4s-issued clients
it's now possible to invoke transformations more conveniently in polymorhic code, via a method in the Transformation
companion object
It is now possible to define static query parameters when using the http trait :
@http(method: "GET", uri: "/foo?bar=baz)
operation Foo {}
Service interfaces now receive the set of all operations tied to resources transitively tied to the service
For instance, when running the code-generator, the Library
interface will now receive a getBook
method, which
wasn't previously the case
service Library {
resources: [Book]
}
resource Book {
read: GetBook
}
@readonly
operation GetBook {
}
- Various codegen fixes and improvements by @Baccata in disneystreaming#677
- fix for timestamp format issue for aws tests by @yisraelU in disneystreaming#675
- Make whitespace around colons consistent by @kubukoz in disneystreaming#682
- Add resource operations to generated service by @Baccata in disneystreaming#686
- fix path segment parsing when suffixed with query by @yisraelU in disneystreaming#689
- Compliancetests fixes improvements by @yisraelU in disneystreaming#680
- restructured timeout call and attemptNarrow by @yisraelU in disneystreaming#708
- [compliance tests] addresses timeouts on the server side by @yisraelU in disneystreaming#712
- Fix ShapeId.parse not working for valid shapes by @kubukoz in disneystreaming#714
- codegen cli should use a non-zero exit code when failing by @daddykotex in disneystreaming#713
This 0.17.0 release of Smithy4s brings a number of improvements on the abstractions implemented by the generated code, in particular in terms of flexibility and user experience.
This release also aims at bringing inter-operability with other tools and projects that Disney Streaming is putting forward to reinforce the Smithy ecosystem, such as smithy-translate and alloy.
In order to achieve these improvements, we've had to break a number of things at different levels. This release is therefore neither source nor binary compatible with the previous ones, and also forces the user to update their Smithy specifications.
The Smithy shapes that were previously residing under smithy4s.api
namespace have moved to the alloy
namespace. Alloy is a standalone library containing Smithy shapes and validators, defined here.
The reason for us to bring this change is to have a language specific location to define shapes that are relevant to the protocols/runtime-behaviours we're putting forward, that could be used by tooling working with other languages than Scala. It was important for us to lose the 4s
suffix, which is short for for Scala
.
This change implies, for instance, that any use of smithy4s.api#simpleRestJson
in your specification will have to be replaced by alloy#simpleRestJson
.
Note that this change, in use cases that follow our documentation, should have no visible effect in the Scala code.
The smithy4sInputDir
setting/task in SBT/mill has been replaced by smithy4sInputDirs
, allowing the user to set several directories where the plugins should look for Smithy files.
We've changed the smithy-sharing mechanism to do two things:
- By default, any dependency declared "normally" in SBT or mill, by means or
libraryDepedencies ++=
ordef ivyDeps
, will be inspected for Smithy files after being resolved. This means that, for instance, if your application has a runtime dependency on a library that was built with Smithy4s and contains Smithy files, your local specs can use the code defined in these Smithy files to create or annotate new shapes. You no longer need to declare those using% Smithy4s
ordef smithy4sIvyDeps
: these are now reserved for libraries containing Smithy files that you do not want your application's runtime to depend on. - Libraries built by Smithy4s automatically track the dependencies that they used during their own code-generation, by storing some metadata in their Jar's manifests. By default, the Smithy4s plugins will also pull those dependencies (which will have been declared upstream using
% Smithy4s
in SBT ordef smithy4sIvyDeps
in mill), for your project's code generation. This facilitates the transitivity of specification-holding artifacts. This mechanism is used, for instance, to communicate to users projects the fact that Smithy4s depends on shapes that are defined in the alloy library, and that these shapes should be made available to user projects, without impacting the user's application runtime, and without requiring any setup from the user.
Depending on your setup, it may be a breaking change, but @deprecated
Smithy-traits now translate to the @deprectated
Scala annotation in the generated code. For instance, if you used @enum
heavily, you'll probably deprecation warnings in your console when compiling. Depending on your scalacOptions
, it is possible that these warnings turn into errors. If you want to silence these particular errors while upgrading, you can do the following:
scalacOptions ++= Seq(
"-Wconf:msg=object Enum in package api is deprecated:silent",
"-Wconf:msg=type Enum in package api is deprecated:silent",
// for Scala 3
"-Wconf:msg=object Enum in package smithy.api is deprecated:silent",
"-Wconf:msg=type Enum in package smithy.api is deprecated:silent"
)
If you use Smithy4s in the ways that were previously advertised in the documentation, you may have to perform some small adjustments.
In particular, the simpleRestJson
extension method that was added to implementations of service-interfaces generated by Smithy4s is now removed, in favour of the SimpleRestJsonBuilder
construct (which now works for any service
Smithy shape that will have been annotated with alloy#simpleRestJson
).
Additionally, some methods that were deprecated in 0.16.x releases have been removed.
The abstractions that the generated code implements and that the runtime interpreters use have undergone some massive changes.
Non-exhaustive list of symbol renames :
old | new |
---|---|
smithy4s.Monadic | smithy4s.kinds.FunctorAlgebra |
smithy4s.Interpreter | smithy4s.kinds.FunctorInterpreter |
smithy4s.Service#asTransformation | toPolyFunction |
smithy4s.Service#transform | fromPolyFunction |
smithy4s.PolyFunction | smithy4s.kinds.PolyFunction |
smithy4s.Transformation | smithy4s.kinds.PolyFunction5 |
smithy4s.GenLift[F]#λ | smithy4s.kinds.Kind1[F]#toKind5 |
- Smithy4s makes a lot of use of polymorphic functions of various kinds. Those are now code-generated (see the
project/Boilerplate.scala
file) to ensure the consistency of the various ways they are being used. This means thatsmithy4s.PolyFunction
has moved tosmithy4s.kinds.PolyFunction
, and that the previoussmithy4s.Transformation
is nowsmithy4s.kinds.PolyFunction5
. This decision ripples in thesmithy4s.Service
interface, which now sportstoPolyFunction
andfromPolyFunction
methods, allowing to turn a finally-encoded implementation into a final one.smithy4s.kinds.PolyFunction2
is also a thing, and may be used in bi-functor contexts. kind
-specific types were created to facilitate the "lift" of constructs to the right kinds. For instance, when inspecting the internals of this library, you might see things likeKind1[IO]#toKind5
where it was previouslyGenLift[IO]#λ
. We're hoping to convey meaning better, although this code is definitely still not trivial (and never will).smithy4s.Transformation
is now a typeclass-like construct, which expresses the fact that a construct can be applied like a function. This construct is used by thetransform
method that is generated on service interfaces, which allows to apply custom behaviour generically on all method invocations in these interfaces.- The
Service
interface takes a singleAlg
type parameter, theOp
parameter has moved to type-member position, facilitating implicit search in some contexts (as well as the writing of some logic). - A bunch of path-dependent type aliases were created in the
Service
interface. - The
compliancetest
module has changed drastically in UX. For those not aware, this module allows to run tests written in Smithy against your own implementation of protocols. This will be useful for third-party libraries that implementsimpleRestJson
(or any other http/rest like protocol), to virtually get tests for free. We don't think this module had any users so far, but we'll slowly be porting some of our tests away from thesmithy4s
repository and into thealloy
repository.
It is now possible to quickly stub a service with a default value (IO.stub
being a good candidate), which can be helpful for testing purposes. The resulting code looks like this :
import smithy4s.hello._
import cats.effect._
val stubbedHelloWorld: HelloWorldService[IO] = new HelloWorldService.Default[IO](IO.stub)
smithy4s.Transformation
has been revised to facilitate the integration with various shapes of transformations. It allows, in particular, to transform a service implementation by applying generic (but polymorphic) behaviour in all of its methods. For instance, this can be used to apply a timeout on all of the methods of a service, or retrying behaviour, etc ...
In particular, the smithy4s.Transformation
companion object contains in particular AbsorbError
and SurfaceError
interfaces that developers can leverage to get their services to go from mono-functor (where all errors are treated as Throwable
) to bi-functor (where errors are surfaced on a per-endpoint basis, forcing the developers to handle them one way or another), and vice-versa.
The generated code now contains bi-functor-specialised ErrorAware
type-aliases. Those, combined with the transformations described above, should make it easier to interop with Bi-functor constructs such as EitherT
or ZIO
.
Adds the ability to have smithy4s-level middleware that is made aware of the Server
and Endpoint
for use in creating middleware implementations. This unlocks creating middleware that is aware of the Smithy traits (Hints
in smithy4s) and shapes in your specification. This means the middleware can apply transformations based on traits applied in a Smithy specification and it can return error responses defined in the Smithy specification. An example of this is authentication. You are now able to create middleware that will check authentication on only the endpoints that require it AND you can return a smithy-defined error response when the authentication is not valid. See the endpoint specific middleware guide for more.
Streamlines and improves how error responses are mapped to their corresponding smithy4s-generated types. It now works such that IF no X-Error-Type
header is found AND the status code doesn't map precisely to an error annotated with @httpCode
AND exactly one error happens to have @error("client")
without @httpCode
, that error will be selected (provided the status code is in the 4xx range). Same for @error("server")
and 5xx range. See the error handling documentation for more.
Previously, smithy4s's HttpEndpoint
was limited to supporting just a small subset of HTTP methods (POST
, GET
, PATCH
, PUT
and DELETE
). This is now mitigated, and all other methods are accepted by HttpEndpoint
, by means of an open-enumeration.
In order to mitigate known security problems, our json parsing logic has hard-limits over the number of elements it will parse from arrays or maps, resulting in an error when receiving payloads with larger collections. Previously, this limit was hardcoded to 1024 elements per collection. This is now configurable, 1024 being the default.
Refinements applied on list/map shapes can now produce parameterised types. This allows, for instance, to have generic
refinements on list
shapes that produce cats.data.NonEmptyList
containing the same types of elements.