logoalt Hacker News

atombenderyesterday at 11:03 PM4 repliesview on HN

For backend web dev, there are advantages. I really like Axum's use of typing:

    pub async fn dataset_stats_handler(
        Path(dataset_id): Path<String>,
        Query(verbose): Query<bool>,
    ) -> impl IntoResponse {
      ...
    }
With a route like:

    .route("/datasets/{dataset_id}/stats", get(dataset_stats_handler))
…the "dataset_id" path variable is parsed straight into the dataset_id arg, and a query string "verbose" is parsed into a boolean. Super convenient compared to Go, and you type validation along with it.

Many other things to like: The absence of context.Context, the fact that handlers can just return the response data, etc.

What I don't like: Async.


Replies

ricardobeatyesterday at 11:57 PM

go is slightly more verbose (surprise) but you can achieve the same thing using struct binding in gin:

    type DatasetStatsQuery struct {
        Verbose bool `form:"verbose"`
    }
    
    func DatasetStatsHandler(c *gin.Context) {
        datasetID := c.Param("dataset_id")
        var query DatasetStatsQuery
        if err := c.ShouldBindQuery(&query); err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
        // query.Verbose == bool
    }}
This is actually a great example - what happens in that Rust version when the input parsing fails? Go makes it explicit.
show 2 replies
xyzzy_plughtoday at 12:56 AM

The Go standard library has learned to interpret path variables as well:

https://go.dev/blog/routing-enhancements

whstltoday at 1:17 PM

A project I work at uses a similar pattern (similar from what I can see):

    func Login(req LoginRequest, cookies Cookies, db *sql.DB) (LoginResponse, error) {
        ...
    }

    router.HandleFunc("POST /signup", fw.Wrap(Login))
It's just a wrapper.

It also serializes/deserializes responses and handles both JSON and templates.

db is just a singleton-lifetime dependency, we often also have ctx, http.Request, http.Response, Cookie, which are request-time lifetimes.

I thought about open-sourcing it but most Golang developers seem to hate it with a passion, so I just gave up, haha.

winridtoday at 2:13 AM

You can not use async right? Maybe not with axum but I imagine there are fully blocking frameworks for rust.