8 comments

[ 2.8 ms ] story [ 42.8 ms ] thread
> What if two patterns overlap but neither is more specific? For example, /posts/{id} and /{resource}/latest both match /posts/latest. There is no obvious answer to which takes precedence, so we consider these patterns to conflict with each other. Registering both of them (in either order!) will panic.

A panic? That's a bad dev experience. Why not say an earlier variable is more general -- or a later variable is more specific? /posts/{id} wins.

Consider /posts/{id} vs:

    /posts/latest/{u}    // wins (later variable)
    /posts/{id}/latest   // wins (more specific)
    /posts/{id}/{id2}    // wins (later variable. id2 must exist)
    /{u}/posts/          // lose (earlier variable)
    /posts/{otherId}     // invalid (same path with different name)
    /latest/{u}          // no conflict
Picking a winner in such a conflict leads to unexpected behavior if ordering changes.
> A panic?

Sure. That's precisely what exceptions (panics) are for: To deal with programmer mistakes identified at runtime that the compiler failed to detect. The use is appropriate.

If you want perfect compile-time safety, Go is not it. It prioritizes other tradeoffs. Such is engineering.

FTA:

“In Go 1.22, the existing code will continue to work, or you could instead write this:

  http.Handle("GET /posts/{id}",
              handlePost2)

Can anybody explain why they chose such a stringified approach for the API and not

  http.Handle(Http.GET, "/posts/{id}",
              handlePost2)
or, if they don’t want to restrict the set of http verbs,

  http.Handle("GET", "/posts/{id}",
              handlePost2)
? I think either would be a better API.
Backwards compatibility promise. They could have introduced new methods instead, but I don't remember the rationale for avoiding that route.
Ignoring the go1 guarantee, what advantage do you see with your suggested API?
It requires less string processing, (for the first option) removes the possibility to mistype a verb, allows for (slightly) better autocomplete, and better reflects how I describe the http protocol. You do “a GET request on an URI”, not a “GET URI”.

I still think it would not be good, though. For me ‘Handle’ sounds like an instruction to do something, but it only adds/registers a handler.

Also, why require multiple calls to, essentially, pass a set of (pattern, handler) pairs? I think I would have chosen to make a single call “here are the patterns to register and their handlers”. Most tools would have to make only one such call.

It possibly also could be more efficient because the API wouldn’t have to have intermediate states where it can handle one type of request, than 2, 3, etc.

> It requires less string processing

Why keep {id}, then? Why not remove the string processing entirely? You may mistype it. You lose better autocomplete. Seems like there is room for significant improvement, not just a minor change. To which there is still an opportunity to introduce a another API, so it's worth finding it.