Skip to content

Commit ed0ca0e

Browse files
committed
suggest hopping through intermediate versions in new-version guide
1 parent 6d94601 commit ed0ca0e

1 file changed

Lines changed: 55 additions & 1 deletion

File tree

guides/new-version.md

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ impl From<MyType> for v1::path::MyType {
212212
// above.
213213
```
214214

215-
In general, there is no need to implement conversions from other prior versions, since you can go through intermediate versions. In some cases it may be more efficient to do so anyway; use appropriate judgment.
215+
In general, don't add `From` impls from other prior versions. (So, if a type changed from `v1` to `v4` to `v9`, avoid implementing conversions from `v9` to `v1` or vice versa.) Instead, hop through intermediate versions in the API trait. In some cases it may be more efficient to have direct conversions to prior versions; use appropriate judgment.
216216

217217
### Add or update re-exports in `latest.rs`
218218

@@ -338,6 +338,60 @@ pub trait MyApi {
338338

339339
If possible (particularly if conversions only use `From` or `TryFrom`), make the prior version a provided method on the trait, with a default implementation that forwards to the corresponding latest versions. See [RFD 619's example API trait](https://rfd.shared.oxide.computer/rfd/619#example-api-trait).
340340

341+
Update changed endpoints to hop through intermediate versions if necessary. For example:
342+
343+
```rust
344+
pub trait MyApi {
345+
#[endpoint {
346+
method = GET,
347+
path = "/instance/spec",
348+
versions = VERSION_THREE..
349+
}]
350+
async fn instance_spec_get(
351+
rqctx: RequestContext<Self::Context>,
352+
) -> Result<
353+
HttpResponseOk<latest::instance_spec::InstanceSpecGetResponse>,
354+
HttpError,
355+
>;
356+
357+
#[endpoint {
358+
operation_id = "instance_spec_get",
359+
method = GET,
360+
path = "/instance/spec",
361+
versions = VERSION_PROGRAMMABLE_SMBIOS..VERSION_NVME_MODEL_NUMBER
362+
}]
363+
async fn instance_spec_get_v2(
364+
rqctx: RequestContext<Self::Context>,
365+
) -> Result<
366+
HttpResponseOk<v2::instance_spec::InstanceSpecGetResponse>,
367+
HttpError,
368+
> {
369+
// Convert from v3 to v2.
370+
Ok(Self::instance_spec_get(rqctx)
371+
.await?
372+
.map(v2::instance_spec::InstanceSpecGetResponse::from))
373+
}
374+
375+
#[endpoint {
376+
operation_id = "instance_spec_get",
377+
method = GET,
378+
path = "/instance/spec",
379+
versions = ..VERSION_PROGRAMMABLE_SMBIOS
380+
}]
381+
async fn instance_spec_get_v1(
382+
rqctx: RequestContext<Self::Context>,
383+
) -> Result<
384+
HttpResponseOk<v1::instance_spec::InstanceSpecGetResponse>,
385+
HttpError,
386+
> {
387+
// Convert from v2 (returned by the `_v2` method) to v1.
388+
Ok(Self::instance_spec_get_v2(rqctx)
389+
.await?
390+
.map(v1::instance_spec::InstanceSpecGetResponse::from))
391+
}
392+
}
393+
```
394+
341395
### Regenerate OpenAPI documents
342396

343397
Run `cargo xtask openapi generate`. If all goes well, you'll see:

0 commit comments

Comments
 (0)