The markdown parsing is broken/disabled for release notes. Sorry about that, I'm chasing the source of a crash that's been bringing this website down for the last couple of days.
## What's Changed
* Fix NIOExtras dependency by @simonbohnen in https://github.com/Apodini/Apodini/pull/444
* Swift 5.7 support by @lukaskollmer in https://github.com/Apodini/Apodini/pull/446
* Update Dependencies by @lukaskollmer in https://github.com/Apodini/Apodini/pull/448
**Full Changelog**: https://github.com/Apodini/Apodini/compare/0.10.0...v0.11
## Semantic Version Major
* Various Small Improvements by @lukaskollmer in https://github.com/Apodini/Apodini/pull/429<details>
<summary>Release Notes</summary>
- ApodiniGRPC:
- Improve handling of enum fields and optional enum fields when en/decoding from/to Protocol Buffers
- Improved error messages for encoding/decoding issues
- Handlers are now sent a `.close` event instead of `.end` when a stream is closed without an accompanying request
- Various internal changes and bug fixes which should not directly affect clients
</details>
* ApodiniAudit and test REST & HTTP best practices by @simonbohnen in https://github.com/Apodini/Apodini/pull/433 and https://github.com/Apodini/Apodini/pull/439 <details>
<summary>Release Notes</summary>
This is the first version of ApodiniAudit, which enables developers to automatically test their APIs against common best practices for REST and HTTP. It introduces the `RESTAuditor` and `HTTPAuditor` Configurations which register the `audit` CLI command. This command performs the audit, currently checking for simple best practices such as adequate length of URL path segments.
- Checkable Best Practices
- URL Best Practices
- [Plural nouns](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniAudit/BestPractices/URLBestPractices/GrammaticalNumberBestPractices.swift) for segments in front of ID parameters (BP14 & BP15)
- Only [lowercase](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniAudit/BestPractices/URLBestPractices/URLSegmentBestPractices/LowercaseURLPathSegments.swift) characters (BP9)
- No [CRUD verbs](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniAudit/BestPractices/URLBestPractices/URLSegmentBestPractices/NoCRUDVerbsInURLPathSegments.swift) (BP18)
- No [file extensions](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniAudit/BestPractices/URLBestPractices/URLSegmentBestPractices/NoFileExtensionsInURLPathSegments.swift) (BP10)
- No [number or symbols](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniAudit/BestPractices/URLBestPractices/URLSegmentBestPractices/NoNumbersOrSymbolsInURLPathSegments.swift) (BP2 & BP8)
- Appropriate path [segment length](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniAudit/BestPractices/URLBestPractices/URLSegmentBestPractices/URLPathSegmentLength.swift) (BP3)
- Endpoints should return [complex types](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniAudit/BestPractices/TypeBestPractices/EndpointHasComplexReturnType.swift) (BP23 & BP73)
- Endpoints should not have [too many parameters](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniAudit/BestPractices/ParameterBestPractices/ReasonableParameterCount.swift) (BP19)
- [ETags](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniAudit/BestPractices/Suggestions/EncourageETags.swift) should be used for caching when appropriate (BP55)
- Added Linguistic Engine using PythonKit
- Python is required to run the linguistic checks
- Updated Actions accordingly (see e.g. [here](https://github.com/Apodini/.github/commit/7d0f6bfe7258e9eea340c8c7bf3ea7bc5e7cb960))
- NLTK and the required corpora can be installed through the [AuditSetupNLTKCommand](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniAudit/CommandLine/AuditSetupNLTKCommand.swift)
- Added [selection](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniAudit/Metadata/SelectBestPracticesMetadata.swift) of BestPractices via Metadata
- Enforcement of Best Practices
- 401 and 403 HTTP status codes are returned upon [ApodiniError](https://github.com/Apodini/Apodini/blob/582c70dbf97eb6b549b739db8f27510a642700e3/Sources/ApodiniNetworking/HTTP/Response.swift#L201) (BP43 & BP44)
- Supportable best practices
- More status codes (see [here](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/Apodini/Response/Status.swift) and tests [here](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Tests/ApodiniHTTPTests/HTTPStatusTests.swift)) (some of BPs 35 - 49)
- [LastModified](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniHTTPProtocol/Information/LastModified.swift) header (BP54)
- Update DatabaseHandler return types and Operation metadata (see e.g. [here](https://github.com/Apodini/Apodini/blob/simonbohnen/pythonkit/Sources/ApodiniDatabase/Handlers/Delete.swift))
</details>
* Update Documentation and Change Blackboard to Shared Repository by @PSchmiedmayer in https://github.com/Apodini/Apodini/pull/438<details>
<summary>Release Notes</summary>
- The `Blackboard` type has been renamed to `SharedRepository`
</details>
* HTTP/2 Streaming by @simonbohnen in https://github.com/Apodini/Apodini/pull/442<details>
<summary>Release Notes</summary>
A lightweight protocol of length-prefixed messages via HTTP/2 streams. The implementation includes:
- Combining HTTP/1.1 array-based streaming with HTTP/2 length-prefixed streaming (see [here](https://github.com/Apodini/Apodini/pull/442/files#diff-8c61fcf38099ab9ea4e96b88af511e5f12c070dfe2b52173714aa3b1658760ad) and [here](https://github.com/Apodini/Apodini/pull/442/files#diff-2092aeab627896031cd28bdf232fc8abf9de3a0a4a3d0a27512f5f9cf4d48ca1))
- Providing a client which speaks this length-prefixed protocol: see [here](https://github.com/Apodini/Apodini/pull/442/files#diff-bc07c94403572167fdfa38342915f242872b62111695e53afa222a75f77a0862) and [here](https://github.com/Apodini/Apodini/pull/442/files#diff-8bab2a5d67c09812c2b6c799b4672598d24cb9be4e9149852fec1e7d989043e1)
</details>
## Semantic Version Minor
* Fix Schedule GitHub Action by @PSchmiedmayer in https://github.com/Apodini/Apodini/pull/435
* Update dependencies by @ApodiniBot in https://github.com/Apodini/Apodini/pull/437
* Update dependencies by @ApodiniBot in https://github.com/Apodini/Apodini/pull/440
## New Contributors
* @simonbohnen made their first contribution in https://github.com/Apodini/Apodini/pull/433
**Full Changelog**: https://github.com/Apodini/Apodini/compare/0.9.2...0.10.0
## What's Change
* Refine the Hostname and Port Configuration Selection Logic by @PSchmiedmayer in https://github.com/Apodini/Apodini/pull/434<details>
<summary>Release Notes</summary>
- Changes the behavior that the bind address port does take prescience over the default HTTP port if there is no explicit port defined by the hostname.
- The Apodini Migrator uses the hostname for the hostname in the API document instead of the bind address.
</details>
**Full Changelog**: https://github.com/Apodini/Apodini/compare/0.9.1...0.9.2
## Semantic Version Minor
* Automatic Tracing and Error Recording by @moritzsternemann in https://github.com/Apodini/Apodini/pull/410<details>
<summary>Release Notes</summary>
- Enables continuous observability of `WebService`s using [apple/swift-distributed-tracing](https://github.com/apple/swift-distributed-tracing), configurable on a per-component level using the `TracingMetadata` or the `trace(isEnabled:)` component modifier.
- Adds a `JaegerBaggageExtractorInstrument` to extract and inject Jaeger-specific baggage values
Example of enabling automated tracing for a component and propagating context to a client service:
```swift
import Apodini
import ApodiniObserve
import Tracing
struct ExampleWebService: WebService {
// ...configuration
var content: some Component {
Group("greeter") {
Greeter()
}.trace()
}
}
struct Greeter: Handler {
@Environment(\.databaseService) var databaseService
@EnvironmentObject var span: Span
func handle() async throws -> String {
let name = databaseService.getName(baggage: span.baggage)
return "Hello, \(name)!"
}
}
```
</details>
* Enable Access-Control-Allow-Origin header by @valentinbootz in https://github.com/Apodini/Apodini/pull/428
* Swift 5.6 Compatibility by @lukaskollmer in https://github.com/Apodini/Apodini/pull/431
**Full Changelog**: https://github.com/Apodini/Apodini/compare/0.9.0...0.9.1
## Semantic Version Major
* Support for ApodiniMigrator 0.3.0 (GRPCMigrator) by @Supereg in https://github.com/Apodini/Apodini/pull/414<details>
<summary>Release Notes</summary>
- The release notes can be found at [https://github.com/Apodini/ApodiniMigrator/releases/tag/0.3.0](https://github.com/Apodini/ApodiniMigrator/releases/tag/0.3.0)
</details>
* Remove `___` suffixes from implicitly created wrapper proto types by @lukaskollmer in https://github.com/Apodini/Apodini/pull/417<details>
<summary>Release Notes</summary>
- gRPC Interface Exporter:
- Changed protobuffer message typename generation to no longer use `___` underscores for auto-generated wrapper types.
- Added `HandlerInputProtoMessageName` and `HandlerResponseProtoMessageName` metadata definitions for explicitly specifying the typenames of a `Handler`'s implicitly generated input and/or output proto message types.
- GraphQL Interface Exporter:
- Added custom scalar types for commonly-used Swift types such as `Date`, `URL`, or `Data`
- `Date` objects are represented as ISO8601-encoded strings
- `URL` objects are represented as strings containing the full and absolute URL
- `Data` objects are represented as base-64 encoded strings
- Added custom scalar types for Swift's integer types with > 32 bits
- the `Int64` scalar type maps to Swift's `Int` and `Int64` types
- the `UInt64` scalar type maps to Swift's `UInt` and `UInt64` types
- (we're assuming that Apodini is running on a 64-bit system here, which should be fine since the probability of someone running Apodini on an old Apple Watch is rather low...)
- There is a flag to disable these custom 64-bit Int scalars, which will cause the GraphQL interface exporter to throw an error instead. (This option is exposed via the `enableCustom64BitIntScalars` flag in the `GraphQL` configuration type)
</details>
* Rename Apodini Deployer Components, Improve CLI Interface, and Fix SwiftLint Errors by @PSchmiedmayer in https://github.com/Apodini/Apodini/pull/420<details>
<summary>Release Notes</summary>
- Rename Apodini Deploy to Apodini Deployer
- Rename Deployment Providers to include the name Deployment Provider in the target and executable names
- Improve the Apodini Deployer Configuration not requiring to use `<Self>` in the Deployment Provider configuration.
- Make the AWS Lambda Deployment Provider API Gateway parameter optional instead of using the `_createNew` magic value.
- Update the invoke functions of the Remote Handler Invocation to use the Swift concurrency features.
- The output of the AWS Deployment provider uses upper case letters at the beginning of all log messages
- Fix SwiftLint Errors and the SwiftLint GitHub Action (CC: @Supereg & @lukaskollmer)
</details>
## Semantic Version Minor
* Decoding, Evaluation, and Result Transformation Error Forwarding by @moritzsternemann in https://github.com/Apodini/Apodini/pull/405<details>
<summary>Release Notes</summary>
Adds support for transparent forwarding of errors that occur during the `Handler` evaluation chain (decoding, evaluation, result transformation) for all interface exporters. The feature can be used by configuring an `ErrorForwarder` for an `Endpoint`.
Example usage:
```swift
struct ErrorForwarderExporter: InterfaceExporter {
func export<H>(_ endpoint: Endpoint<H>) -> () where H : Handler {
endpoint[ErrorForwarder.self] = try! ErrorForwarder { error in
print("received error", error)
}
}
// ...
}
```
</details>
* Add Document Export by @valentinbootz in https://github.com/Apodini/Apodini/pull/412<details>
<summary>Release Notes</summary>
- Update ApodiniMigrator and ApodiniDocumentExport dependencies to refactor ApodiniMigration
</details>
* Improve Parameter Handling by @lukaskollmer in https://github.com/Apodini/Apodini/pull/416<details>
<summary>Release Notes</summary>
- Added support for `Date` objects as path or query parameters in the HTTP and REST interface exporters
</details>
* Update dependencies by @ApodiniBot in https://github.com/Apodini/Apodini/pull/418
* Fix the TestWebService tests by @lukaskollmer in https://github.com/Apodini/Apodini/pull/419
* Fix the AWS Lambda Deployment Provider by @PSchmiedmayer in https://github.com/Apodini/Apodini/pull/421
**Full Changelog**: https://github.com/Apodini/Apodini/compare/0.8.0...0.9.0
## Semantic Version Major
* Add Basic GraphQL Support by @lukaskollmer in https://github.com/Apodini/Apodini/pull/402<details>
<summary>Migration Guide</summary>
- **Breaking:** Renamed the `tlsConfigurationBuilder` argument of the `HTTPConfiguration` to `tlsConfiguration`.
- **Breaking:** Fixed typos in the `Response` and `AnyEndpointParameter` types, renaming `typeErasured...` to `typeErased...`
- **Breaking:** Removed the `gRPCMethodName` modifier, use `endpointName(_:)` instead
- Added a new `GraphQLInterfaceExporter`
- Protobuffer: Added support for the `Foundation.Date`, `Foundation.URL`, and `Foundation.UUID` types
- Added a new "endpoint name" API, which allows users to specify endpoint names, either at handler-type-level (via the `metadata` property), or at DSL-level (via the `endpointName(_:)` modifier. Endpoint names are made available to interface exporters, which can use them to generate user-facing names for the individual endpoints in the exported API.
- Added a few convenience functions and types to make `Configuration`s conditional. This allows enabling/disabling configuration entries based on certain conditions such as whether HTTPS is enabled, the build type (debug vs release), or others.
</details>
## Semantic Version Minor
* Restore AWS Lambda Compatibility by @lukaskollmer in https://github.com/Apodini/Apodini/pull/406
**Full Changelog**: https://github.com/Apodini/Apodini/compare/0.7.1...0.8.0
## Semantic Change Minor
* Configure the Root Path for HTTP-based Exporters by @PSchmiedmayer in https://github.com/Apodini/Apodini/pull/409
**Full Changelog**: https://github.com/Apodini/Apodini/compare/0.7.0...0.7.1
## Semantic Version Major
* Re-implement the gRPC interface exporter and the ProtobufferCoding target by @lukaskollmer in https://github.com/Apodini/Apodini/pull/384<details>
<summary>Migration Guide</summary>
- Rewrote the ApodiniGRPC and ProtobufferCoding targets, to follow the gRPC and protobuf specs more closely.
- Web Services no longer need to import and enable the ApodiniProtobuffer interface exporter
- Added a `.close` case to the `ConnectionState` enum.
- This case indicates that a connection was closed after the most recent request, but that the close event didn't have a request associated with it.
- The connection states are now as follows (from the perspective of a client-side-streaming Handler):
- `open`: The connection just received a request, and the client did not signal that it wants the connection be closed.
- `end`: The connection just received a request, and the client signalled that this was the last request and that the connection should be closed afterwards
- `close`: The client signalled that the connection should be closed, but did not send a request alongside the close request. In this case the handler is invoked with the most-recent request (to make sure that e.g. accessing `@Parameter` properties doesn't result in a crash), but should ignore that request and instead return its `.final` response.
- It is guaranteed that the last connection state sent to a client-side-streaming handler is either `end` or `close`, and that the handler will only ever receive one of the two.
- This change requires corresponding changes to streaming handlers, since the previous pattern of simply using an if statement to check whether the connection is closing now no longer covers all possible connection states:
- Previous:
```swift
struct NameCollector: Handler {
@Environment(\.connection) var connection
@Parameter var name: String
@State private var names: [String] = []
func handle() -> Response<String> {
if connection.state == .end {
return .final("Received names: \(names.joined(separator: ", ")).")
} else {
names.append(name)
return .send()
}
}
}
```
- New:
```swift
struct NameCollector: Handler {
@Environment(\.connection) var connection
@Parameter var name: String
@State private var names: [String] = []
func handle() -> Response<String> {
switch connection.state {
case .open:
names.append(name)
return .send()
case .end:
names.append(name)
fallthrough
case .close:
return .final("Received names: \(names.joined(separator: ", ")).")
}
}
}
```
</details>
* Update ApodiniMigration to ApodiniMigrator 0.2.0; bump ApodiniTypeInformation to 0.3.0 by @Supereg in https://github.com/Apodini/Apodini/pull/404<details>
<summary>Migration Guide</summary>
* Updated `ApodiniMigrator` to [0.2.0](https://github.com/Apodini/ApodiniMigrator/releases/tag/0.2.0)
* Updated `ApodiniTypeInformation` to [0.3.0](https://github.com/Apodini/ApodiniTypeInformation/releases/tag/0.3.0)
</details>
## Semantic Version Minor
* Update GitHub Actions and Set the Platform Requirement to macOS 11 by @PSchmiedmayer in https://github.com/Apodini/Apodini/pull/374
* Tracing Configuration for ApodiniObserve by @moritzsternemann in https://github.com/Apodini/Apodini/pull/388<details>
<summary>Release Notes</summary>
- Enables configuration of tracing backends in the Apodini Configuration DSL through `TracingConfiguration` and `InstrumentConfiguration`
- Adds convenience `InstrumentConfiguration`s for OpenTelemetry backends
- Enables tracing of `WebService`s using the `Tracer` exposed through the `Application`
</details>
* Use a port range for the LocalhostDeploymentProvider that can not be registered at IANA by @PSchmiedmayer in https://github.com/Apodini/Apodini/pull/390<details>
<summary>Release Notes</summary>
Changed the localhost deployment provider's default ports from 5000 (and up) to 52000 (and up), to avoid conflicts with macOS 12's "Airplay Receiver" feature (which, unless disabled, also listens on 5000)(https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers) of 52000 and onwards.
</details>
* Adjust visibility of the initializer of HandlerMetadataModifier by @Supereg in https://github.com/Apodini/Apodini/pull/399<details>
<summary>Release Notes</summary>
Fixed an issue where `HandlerMetadataModifier` couldn't be directly instantiated, due to erroneous visibility of `init(modifies:with:)`.
</details>
* Add XCTApodiniNetworking product by @valentinbootz in https://github.com/Apodini/Apodini/pull/408
## Other Changes
* Update Metadata Documentation by @PSchmiedmayer in https://github.com/Apodini/Apodini/pull/400
* Fix Typos in the Documentation by @ridvan-cln in https://github.com/Apodini/Apodini/pull/381
## New Contributors
* @valentinbootz made their first contribution in https://github.com/Apodini/Apodini/pull/408
**Full Changelog**: https://github.com/Apodini/Apodini/compare/0.6.2...0.7.0
## Semantic Change Minor
* Add a Default Value for the Address of the BindAddress by @PSchmiedmayer in https://github.com/Apodini/Apodini/pull/387
**Full Changelog**: https://github.com/Apodini/Apodini/compare/0.6.1...0.6.2
## What's Changed
* Remove Unsafe Build Flags by @PSchmiedmayer in https://github.com/Apodini/Apodini/pull/386
**Full Changelog**: https://github.com/Apodini/Apodini/compare/0.6.0...0.6.1