Skip to content

Commit

Permalink
support for specifying version numbers in API endpoints (#1115)
Browse files Browse the repository at this point in the history
  • Loading branch information
davepacheco authored Nov 13, 2024
1 parent 32b50e1 commit 135934e
Show file tree
Hide file tree
Showing 71 changed files with 3,602 additions and 195 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ starter.start()
+
We'd like to remove the `HttpServerStarter` altogether, so let us know if you're still using it for some reason.

* https://github.com/oxidecomputer/dropshot/pull/1115[#1115] Dropshot now includes **experimental** support for hosting multiple versions of an API at a single server and routing to the correct version based on the incoming request. See documentation for details. If you don't care about this, you can mostly ignore it, but see "Breaking Changes" below.
+
By "experimental" we only mean that the API may change in upcoming releases.

=== Breaking Changes

* Dropshot now expects that APIs use https://semver.org/[Semver] values for their version string. Concretely, this only means that the `version` argument to `ApiDescription::openapi` (which generates an OpenAPI document) must be a `semver::Version`. Previously, it was `AsRef<str>`.
* If you're invoking `ApiEndpoint::new` directly or constructing one as a literal (both of which are uncommon), you must provide a new `ApiEndpointVersions` value describing which versions this endpoint implements. You can use `ApiEndpointVersions::All` if you don't care about versioning.


== 0.12.0 (released 2024-09-26)

https://github.com/oxidecomputer/dropshot/compare/v0.11.0\...v0.12.0[Full list of commits]
Expand Down
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions dropshot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ percent-encoding = "2.3.1"
rustls = "0.22.4"
rustls-pemfile = "2.1.3"
scopeguard = "1.2.0"
semver = "1.0.23"
serde_json = "1.0.132"
serde_path_to_error = "0.1.16"
serde_urlencoded = "0.7.1"
Expand Down Expand Up @@ -105,12 +106,15 @@ trybuild = "1.0.101"
# Used by the https examples and tests
pem = "3.0"
rcgen = "0.13.1"
# Using rustls-tls because it appears the rcgen-generated certificates are not
# supported by the native Windows APIs.
reqwest = { version = "0.12.9", features = ["json", "rustls-tls"] }
# Used in a doc-test demonstrating the WebsocketUpgrade extractor.
tokio-tungstenite = "0.24.0"

[dev-dependencies.reqwest]
version = "0.12.9"
# Using rustls-tls because it appears the rcgen-generated certificates are not
# supported by the native Windows APIs.
features = [ "json", "rustls-tls" ]

[dev-dependencies.rustls-pki-types]
version = "1.10.0"
# Needed for CertificateDer::into_owned
Expand Down
10 changes: 5 additions & 5 deletions dropshot/examples/api-trait-alternate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,14 @@ mod api {
pub(crate) counter: u64,
}

// A simple function to generate an OpenAPI spec for the trait, without having
// a real implementation available.
// A simple function to generate an OpenAPI spec for the trait, without
// having a real implementation available.
//
// If the interface and implementation (see below) are in different crates, then
// this function would live in the interface crate.
// If the interface and implementation (see below) are in different crates,
// then this function would live in the interface crate.
pub(crate) fn generate_openapi_spec() -> String {
let api = counter_api_mod::stub_api_description().unwrap();
let spec = api.openapi("Counter Server", "1.0.0");
let spec = api.openapi("Counter Server", semver::Version::new(1, 0, 0));
serde_json::to_string_pretty(&spec.json().unwrap()).unwrap()
}
}
Expand Down
11 changes: 6 additions & 5 deletions dropshot/examples/api-trait-websocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@ mod api {
pub(crate) counter: u8,
}

// A simple function to generate an OpenAPI spec for the server, without having
// a real implementation available.
// A simple function to generate an OpenAPI spec for the server, without
// having a real implementation available.
//
// If the interface and implementation (see below) are in different crates, then
// this function would live in the interface crate.
// If the interface and implementation (see below) are in different crates,
// then this function would live in the interface crate.
pub(crate) fn generate_openapi_spec() -> String {
let my_server = counter_api_mod::stub_api_description().unwrap();
let spec = my_server.openapi("Counter Server", "1.0.0");
let spec =
my_server.openapi("Counter Server", semver::Version::new(1, 0, 0));
serde_json::to_string_pretty(&spec.json().unwrap()).unwrap()
}
}
Expand Down
11 changes: 6 additions & 5 deletions dropshot/examples/api-trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,15 @@ mod api {
pub(crate) counter: u64,
}

// A simple function to generate an OpenAPI spec for the trait, without having
// a real implementation available.
// A simple function to generate an OpenAPI spec for the trait, without
// having a real implementation available.
//
// If the interface and implementation (see below) are in different crates, then
// this function would live in the interface crate.
// If the interface and implementation (see below) are in different crates,
// then this function would live in the interface crate.
pub(crate) fn generate_openapi_spec() -> String {
let description = counter_api_mod::stub_api_description().unwrap();
let spec = description.openapi("Counter Server", "1.0.0");
let spec = description
.openapi("Counter Server", semver::Version::new(1, 0, 0));
serde_json::to_string_pretty(&spec.json().unwrap()).unwrap()
}
}
Expand Down
2 changes: 1 addition & 1 deletion dropshot/examples/petstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn main() -> Result<(), String> {
api.register(update_pet_with_form).unwrap();
api.register(find_pets_by_tags).unwrap();

api.openapi("Pet Shop", "")
api.openapi("Pet Shop", semver::Version::new(1, 0, 0))
.write(&mut std::io::stdout())
.map_err(|e| e.to_string())?;

Expand Down
2 changes: 1 addition & 1 deletion dropshot/examples/schema-with-example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn main() -> Result<(), String> {
let mut api = ApiDescription::new();
api.register(get_foo).unwrap();

api.openapi("Examples", "0.0.0")
api.openapi("Examples", semver::Version::new(0, 0, 0))
.write(&mut std::io::stdout())
.map_err(|e| e.to_string())?;

Expand Down
Loading

0 comments on commit 135934e

Please sign in to comment.