Rust SDK for Compute@Edge.
This Rustdoc page is a reference for how to use individual APIs from this SDK. For a guide-level introduction to using Compute@Edge with this SDK, see Rust on Compute@Edge at the Fastly Developer Hub.
Migrating from SDK version 0.5.*
and earlier
Version 0.6.0
introduced some substantial changes to the API to improve convenience,
capability, and discoverability. While there are many changed names and new types, the execution
model of a Compute@Edge program has not changed. This guide highlights the changes that most
existing Compute@Edge programs will need to make in order to work with the improved API.
New Request
and Response
; no more RequestExt
and ResponseExt
Replace Request<Body>
with [Request
], and Response<Body>
with [Response
], and then remove
references to RequestExt
and ResponseExt
.
In previous versions of the API, Request
and Response
were provided by the third-party
[http
] crate. While those types are flexible enough to represent Compute@Edge HTTP values, the
new types are purpose-built for Compute@Edge and include a number of conveniences, such as
automatic conversion of method argument types and built-in support for JSON and form
data. Methods like Request::send()
that were previously in the extension traits RequestExt
and ResponseExt
are now defined directly on the types, so those traits are no longer needed.
For example, a minimal program using [#[fastly::main]
][main
] now looks like:
use fastly::{Error, Request, Response};
#[fastly::main]
fn main(ds_req: Request) -> Result<Response, Error> {
Ok(ds_req.send("example_backend")?)
}
"Client" instead of "downstream"
Call [Request::from_client()
] to get the client request, instead of the previous
fastly::downstream_request()
function.
Other functions and methods that used "downstream" to refer to the client that makes the initial
HTTP request now also use "client". For example, Response::send_downstream()
is now
[Response::send_to_client()
], and downstream_client_ip_addr()
is now
[Request::get_client_ip_addr()
].
Header methods instead of HeaderMap
Access headers directly through [Request
] and [Response
], rather than through
[http::header::HeaderMap
][::http::header::HeaderMap
]. For example, code that previously
looked like:
let my_val = req.headers().get(header_name);
req.headers_mut().insert(other_header_name, header_value);
Should now look like:
# let mut req = fastly::Request::get("/");
# let header_name = "";
# let other_header_name = "";
# let header_value = "";
let my_val = req.get_header(header_name);
req.set_header(other_header_name, header_value);
Automatic argument conversion
Pass trusted string literals and other similar types to functions like [Request::get_header()
]
directly, rather than converting them explicitly.
In previous Compute@Edge programs, it was very common to see code like:
HeaderName::try_from("my-header").unwrap()
This has an explicit type conversion and error handling, despite the fact that we know the
string "my-header"
will always be a valid header name.
Many method arguments now have types like impl ToHeaderName
rather than HeaderName
, allowing
you to mix and match strings, byte vectors, and other types into your argument types with
conversions performed automatically. See the documentation of the [convert
] module's traits
like [ToHeaderName
][convert::ToHeaderName
] for details about which types can be converted,
and when to watch out for panics.
Builder-style methods on Request
and Response
Remove uses of http::request::Builder
and http::response::Builder
, and use the methods of
[Request
] and [Response
] prefixed by with_
to use builder-style method chaining. For example:
# use fastly::{Error, Request};
# fn f() -> Result<(), Error> {
Request::get("https://example.com")
.with_header("my-header", "hello!")
.with_header("my-other-header", "Здравствуйте!")
.send("example_backend")?;
# Ok(()) }
There are still non-builder-style getter and setter methods on [Request
] and [Response
], so
you can mix and match styles. For example:
# use fastly::{Error, Request};
# fn f(needs_translation: bool) -> Result<(), Error> {
let mut req = Request::get("https://example.com").with_header("my-header", "hello!");
if needs_translation {
req.set_header("my-other-header", "Здравствуйте!");
}
req.send("example_backend")?;
# Ok(()) }