You’ve all been waiting for another release, and I’m happy to announce that gotham 0.5 is finally here! With this release, we have several new faces on the team:

Together with the existing maintainers, we brought you some exiting changes.

Async/Await support

As futures and async/await has been standardized in Rust, we have moved from futures 0.1 to the new API. Your handler function can now be a true async function:

async fn foo_create_response() -> Response<Body> {
	unimplemented!()
}

async fn foo_handler(state: State) -> HandlerResult {
	let res = foo_create_response().await;
	Ok((state, res))
}

fn router() -> Router {
	build_simple_router(|router| {
		route.get("/foo").to_async(foo_handler);
	})
}

Furthermore, it is possible to take a reference to the State, allowing for usage of the ? shorthand when dealing with Results:

async fn foo_create_response() -> anyhow::Result<Response<Body>> {
	unimplemented!()
}

async fn foo_handler(state: &mut State) -> Result<Response<Body>, HandlerError> {
	let res = foo_create_response().await?;
	Ok(res)
}

fn router() -> Router {
	build_simple_router(|router| {
		router.get("/foo").to_async_borrowing(foo_handler);
	})
}

As you’ve seen in the above code, we are now also using anyhow instead of the now outdated failure crate.

Unfortunately, there is no support for closures yet with borrowing support, so .to_async_borrowing(|state: &mut State| /* code */) does not work as of today, and you’ll have to stick with .to_async(|state| async move { /* code */ }).

Path Matchers

We have improved the behaviour of path matchers in gotham 0.5 as well as included a new path matcher:

  • we improved status code “combination” when path matchers are combined
  • we fixed a bug where a path matcher would change the Allow header of HTTP OPTIONS requests to include methods that have no route
  • we changed the Accept header matcher to support quality-weighted syntax (eventhough qualities are ignored) and to support wildcards like image/* and */*
  • we changed the Content-Type header matcher to support parameters, so that text/plain; charset=utf-8 would be matched when a route is looking for text/plain
  • we added a new matcher for the Access-Control-Request-Method header to make it easier to deal with CORS preflight requests

WebSocket support

Gotham now has connection upgrades enabled, and therefore enables the use of WebSockets. Please check out the examples to find out how websockets can be used in gotham today.

Glob Names

The glob processing in our router has been improved to allow for multiple named globs in one path:

fn router() -> Router {
	build_simple_router(|router| {
		router.get("/foo/*first/bar/*second").with_path_extractor::<FooBarExtractor>().to(foo_bar_handler);
	})
}

Miscellaneous

In addition to above changes, we have updated a lot of dependencies and have updated all of our examples to reflect the changes. Gotham is now also re-exporting some of its dependencies including anyhow, hyper and rustls in an effort to reduce the possibility of a version mismatch. Speaking of rustls, TLS support is now behind a feature flag that is enabled by default. All projects that don’t need TLS support in gotham, e.g. because they are behind a reverse proxy, can now disable TLS support and get rid of the unused dependencies.

A huge thanks to everyone that contributed to this release, it wouldn’t be this awesome without your help! If there is something missing in this release that you’d like to see, please reach out to us. You can do that using GitHub issues or Gitter chat, and of course you are more than welcome to hand in Pull Requests.