httpgourl-routinghttprouter

Correct way to match URL path to page name with URL routing in Go?


I'm making a Go website (small service), and didn't know how a page URL was verified as correct or not found 404. Eventually I learned that http request routers / multiplexers exist.

Example:

eg.com/articles/animals/Hippos-are-aquatic-and-land-dwelling    = go to page
eg.com/articles/animals/Hippos-are-typofrifjirj     = 404 not found page

Right now I only see one way to do this, you somehow have a list of articles the website has, and you pass it into the router somehow. How should you get that list of articles?

For a dynamic relational database site: Do you query your database for article titles, and make that a map string?

For static files on a static website: you use some http fileserver dir function in the router or net/http?

If so, for the database, does that mean you have to query your database every single time a page is visited? Or do you store the list of articles in a file or something and update it each time a new article is made?

Also, I would plan to use https://github.com/julienschmidt/httprouter or similar.


Solution

  • Here's how to do it with the net/http router assuming that everything after /articles/animals/ in the path is the id of an article:

    Register the handler using a trailing slash for match on all paths with the prefix `/articles/animals/':

    mux.HandleFunc("/articles/animals/", animalHandler)
    

    In the handler, strip the /articles/animals/ to get the id of the article. Look up the article in the database. Respond with 404 if not there.

    func animalHandler(w http.ResponseWriter, r *http.Request) {
      id := strings.TrimPrefix(r.URL.Path, "/articles/animals/"))
      article, err := queryArticleByID(id) 
      if err == errNotFound {
         http.Error(w, "internal error", http.StatusNotFound)
         return
      } else if err != nil {
         log.Println(err)
         http.Error(w, "internal error", http.StatusInternalError)
      }
      ... render the article
    }
    

    This example assumes that the queryArticleByID() function queries the database and returns errNotFound if no article is present for the give id.

    Regarding caching: The queryArticleByID() can check a cache before querying the database. Any caching is independent of how routing is handled.