Announcing Gotham 0.2

Since the first release of the Gotham web framework in August 2017, we've been excitedly watching the community grow and get involved in the project. Today we're pleased to announce the release of version 0.2, which includes new features and refinements identified by the community as well as some from our own wishlist.

Some highlights from version 0.2, out of the 99 issues and PRs that we've closed in the last 6 months:

  • New API for building a Router
  • Improvements to documentation and examples
  • Overhauled testing API
  • Path extractors and query string extractors work via Serde now
  • Catching application panics to keep the server process alive

Our thanks to everybody involved in the Gotham community by asking questions, providing feedback, and opening issues and pull requests. Anyone who'd like to get involved should come join us on Gitter or GitHub.

We've started adding some issues to the 0.3 roadmap, to get an idea of what we'd like to tackle next. Some of the noteworthy ones on our list so far:

  • Async static file serving
  • A more convenient method of dealing with request bodies (form data being the priority)
  • Track the evolution of Tokio 0.2 and Futures 0.2, and adapt Gotham to suit the needs of the Rust ecosystem as it is updated for the reformed Tokio
  • Track the adoption of the http crate by hyper, and change Gotham to use the new types for dealing with HTTP

You can find out more about the Gotham web framework at https://gotham.rs.

We'd again like to say a sincere thank you to the developers and communities of all our dependencies, and the Rust language. We're excited for what 2018 will bring to the Rust ecosystem.

Bradley and Shaun

19 Likes

I have started an attempt to convert a toy app of mine to Gotham (from Nickel), and so far I like the impression. I do have some questions ... Is this thread a good place to ask them?

  1. Using a route with route.get("/prefix/:name").with_path_extractor::<MyPathExtractor>().to(my_handler);, name matches only a url segment, i.e. someting that does not contain a slash. Can I get it to take anything (including slashes) that comes after /prefix/ ?

  2. I see there is a work-in-progress diesel middleware in the repo. Is it possible to use that (not for production, just trying stuff out). Since it's not published on crates.io and it's not a separate repo, I don't know what to write in my Cargo.toml to access it?

1 Like

It’s been great working with gotham so far! Great work guys.

1 Like

Hi @kaj

  1. We actually don't have path extraction in the way you're looking to do it, however we do already have glob support so this wouldn't be to hard to add in. Any chance you could log this feature request in our issue tracker? In the interim here is an example showing how to access components such as the request URI.

  2. I've actually not tried that yet. There may be some nuances but using a git dependency within Cargo.toml and pointing to https://github.com/gotham-rs/gotham/releases/tag/0.2.0 should do the trick as Cargo understands how to use workspaces. If you can't make that happen let me know and i'll run it up.

Happy to take questions anywhere you're comfortable, our Gitter chat room is friendly and helpful as well, you're most welcome to join - gotham-rs/gotham - Gitter.

Ok, I'll think some more of what behaviour I actually want for 1, and try to write an issue for it later.

For 2, yes, I now have the following in my dependencies and it seems to work just fine! Thank you!

gotham = { git = "https://github.com/gotham-rs/gotham", tag="0.2.0" }
gotham_derive = { git = "https://github.com/gotham-rs/gotham", tag="0.2.0" }
gotham_middleware_diesel = { git = "https://github.com/gotham-rs/gotham", tag="0.2.0" }

(I changed the gotham and gotham_derive dependencies to git as well, to avoid having a conflict between my direct dependency and the indirect dependency through the middleware.)

Thanks, I've kicked this off at https://github.com/gotham-rs/gotham/issues/175 so it doesn't forgotten as it is likely to be more generally applicable. Would appreciate you adding a comment outlining any further needs you might come up with.

I've been migrating some code from Iron to Gotham, and it's been a pleasant experience so far.

One thing I'm not yet sure how to deal with in Gotham is persistent server-side state. This was pretty easy to deal with in Iron thanks to the persistent middleware.

Is anything like this on the roadmap for Gotham?

2 Likes

Hi @suicas - Great to hear you're having a good experience so far!.

From a quick look at the persistent Iron middleware I suspect that Gotham session support will work for you here. The docs for that are available at gotham::middleware::session - Rust and more importantly we have some examples for working with Sessions at https://github.com/gotham-rs/gotham/tree/master/examples/sessions

Let me know how that works out for you.

Hi @bradleybeddoes,

I'm also moving from Iron to Gotham and the persistent middleware stores data on the server between requests, for example a shared DB connection that is only initialized once at the beginning and then shared between threads.

Gotham sessions store data on the client side as cockies if I understand it correctly, please correct me if I'm wrong.

I enjoy using Gotham and I'm looking foreward for newer releases. Thanks for your great work!

Hi @willi_kappler, I am just about to head off for the day but the Gotham session middleware stores all data server side. It defines a Backend trait that can be implemented by any backend you'd like. Right now we've shipped an in memory implementation which means that terminating a Gotham instance will also terminate all sessions it has established. We're already planning a Redis backend to persist across multiple (possibly dynamically scaled) instances. Any other sort of data store you might need would also work here once a Backend was implemented.

On the client side all we're doing is setting a cookie containing a random session identifier, no session data per se.

Alternatively if you're wanting to implement your own middleware the NewMiddleware trait is responsible for spawning a Middleware instance for every request entering the system. That means your NewMiddleware can setup something shared, such as a database pool, and then provide an appropriate reference each time Middleware is spawned.

Here is a very brief gist I am planning on turning into an official example in the near term, this shows the same concept but for NewHandler / Handler. An actual NewMiddleware / Middleware implementation we've partially completed can be found in our repo.

Either way I am confident we have the mechanism in place to do what is needed, happy to discuss further to figure out best approach(es).

1 Like

Hi @bradleybeddoes,

thanks a lot for your detailed reply - I was totally wrong, sorry for that! Loks like Gotham has everything I need and I'll have a look at your gist and let you know how it worked out for me. Thanks again!

Thanks, will take a look at that.

I was mostly interested in persistent/shared state outside of sessions (e.g. a global hit counter for the server rather than per user), but haven't gone through the docs fully to see if that's possible yet.

@suicas - the NewMiddleware / Middleware split I discussed above with @willi_kappler is what you'll want for that situation (along with a method to safely modify your data residing in the struct implementing the NewMiddleware trait of course).

Sounds perfect, I've got some spare time coming up, so will give that a go and let you know if I encounter any difficulties (though it looks pretty straightforward from what I can see).