2022-03-22 00:14:14 +00:00
|
|
|
---
|
|
|
|
title: "Site Update: Axum"
|
|
|
|
date: 2022-03-21
|
|
|
|
---
|
|
|
|
|
|
|
|
I have made a bunch of huge changes to my website that hopefully you won't
|
|
|
|
notice unless you read this post that points them out to you. I have redone how
|
|
|
|
the website's URL routing works to use
|
|
|
|
[axum](https://tokio.rs/blog/2021-07-announcing-axum) instead of
|
|
|
|
[warp](https://docs.rs/warp/latest/warp/).
|
|
|
|
|
|
|
|
I chose warp fairly arbitrarily when I was getting into the swing of Rust. This
|
|
|
|
choice turned out to be a bit of a mistake. Don't get me wrong, warp is a
|
|
|
|
fantastic framework, but overall I've not been happy with how it impacts compile
|
|
|
|
times. Warp works by pushing a lot of the complexities with HTTP routing into
|
|
|
|
the type system. This can lead to undebuggable inscruitable types that make it
|
|
|
|
really hard to understand what is wrong. Here is the autogenerated type for the
|
|
|
|
`/blog/:name` route:
|
|
|
|
|
|
|
|
```
|
|
|
|
warp::filter::and::And<warp::filter::and::And<impl warp::filter::FilterBase<Extract = (), Error = Infallible> + warp::Filter + std::marker::Copy, Exact<warp::path::internal::Opaque<main::{closure#0}::__StaticPath>>>, warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<warp::filter::and::And<warp::filter::and::And<impl warp::filter::FilterBase<Extract = (), Error = Infallible> + warp::Filter + std::marker::Copy, impl warp::filter::FilterBase<Extract = (std::string::String,), Error = Rejection> + warp::Filter + std::marker::Copy>, impl warp::filter::FilterBase<Extract = (), Error = Rejection> + warp::Filter + std::marker::Copy>, impl warp::filter::FilterBase<Extract = (Arc<app::State>,), Error = Infallible> + warp::Filter + Clone>, impl warp::filter::FilterBase<Extract = (), Error = Rejection> + warp::Filter + std::marker::Copy>, fn(std::string::String, Arc<app::State>) -> impl warp::Future<Output = Result<Opaque(DefId(0:1249 ~ xesite[3495]::handlers::blog::post_view::{opaque#0}::{opaque#0}), []), Rejection>> {blog::post_view}>>
|
|
|
|
```
|
|
|
|
|
|
|
|
[What the heck is that? Is that a binary tree?](conversation://Numa/delet)
|
|
|
|
|
|
|
|
[Yep. It's insufferable to try and debug too.](conversation://Cadey/coffee)
|
|
|
|
|
|
|
|
Yeah, it's really hard to understand what's going on in error messages because
|
|
|
|
of this. This also means that the routes are put into a binary tree in the type
|
|
|
|
system, which means if your tree is unbalanced then you get slower compile times
|
|
|
|
and a slight hit at runtime as the framework traverses your binary tree to
|
|
|
|
figure out what to do. This has also made it difficult for me to add features
|
|
|
|
such as [historical views of my RSS feed](https://github.com/Xe/site/issues/419)
|
|
|
|
or other things I want to add like the April Fools day feature I've been working
|
|
|
|
on.
|
|
|
|
|
|
|
|
When I went out framework shopping, I tried a few things and got reccomendations
|
|
|
|
from a trusted friend before I finally settled on axum as the heart of this
|
2022-03-22 18:36:36 +00:00
|
|
|
website. Axum has a few major advantages that brought me "in the door":
|
2022-03-22 00:14:14 +00:00
|
|
|
|
|
|
|
- It's maintained by the tokio team
|
|
|
|
- It leverages the type system of Rust to make writing handlers easier
|
|
|
|
- It uses extractors (think lenses) to help you pick out the subset of data you
|
|
|
|
need, not blindly giving you everything and hoping you figure it out
|
|
|
|
- It has sub-routers which can have different middleware stacks than the main
|
|
|
|
one (useful for things like API authentication)
|
|
|
|
|
|
|
|
And it has these disadvantages:
|
|
|
|
|
|
|
|
- Writing middleware is kinda weird (though this may be because I'm not used to
|
|
|
|
working with tower), but easy once you get the general flow of things
|
|
|
|
- I can't find a way to have the template data get continuously piped to client
|
|
|
|
connections instead of rendering it to a buffer and then writing that buffer
|
|
|
|
to the client
|
|
|
|
- It doesn't have the biggest mindshare and one of the best ways to get unstuck
|
|
|
|
at the time of writing this article is to ask on their Discord server
|
|
|
|
|
|
|
|
Overall, I've been happy with the experience of porting over my site to using
|
|
|
|
Axum. I did [a stream on Twitch](https://www.twitch.tv/videos/1429533858) where
|
|
|
|
I ported it all over if you want to watch the process and hear my thought
|
|
|
|
processes as I was figuring things out.
|
|
|
|
|
|
|
|
As users, nothing should have changed about this site. However I'm almost
|
|
|
|
certain that I did forget to port _something_ over, so if I missed something you
|
|
|
|
rely on, [get in contact](/contact). I have not gotten the Patreon API
|
|
|
|
interoperability code fixed yet, so that is the next major issue. I am going to
|
|
|
|
figure out how refresh tokens work the hard way and make the patrons page
|
|
|
|
auto-updating instead of having to [manually get a new API key every
|
|
|
|
month](https://github.com/Xe/site/blob/main/docs/patron-page.org). I am also
|
|
|
|
looking into having that patrons page be updated by a cronjob that emits json to
|
|
|
|
the disk and have my site load from that instead of just hoping that the patreon
|
|
|
|
API credentials are up to date. We'll see how that goes, but you can track that
|
|
|
|
[here](https://github.com/Xe/site/issues/442). I will likely do a livestream for
|
|
|
|
this.
|
|
|
|
|
|
|
|
I have also contacted a copyeditor for my blog. I am so happy with the results
|
|
|
|
so far. [My Devops post](/blog/social-quandry-devops-2022-03-17) was the first
|
|
|
|
thing that the editor reviewed and they absolutely tore my first draft in half
|
|
|
|
and helped me put the parts back together into something more palateable. I am
|
|
|
|
beyond satisfied with this and will continue to use this editor in the future. I
|
|
|
|
wish I had gotten a copyeditor sooner.
|