Part 1 , Part 2

HTTP Api’s often use the url path to identify resource name, id and possibly an action. These parts of the URL path are divided by the / character. Here is an example of using path parameters to implement a key value store where data is saved using the following request GET /set/$key/$value and retrieved using the request GET /get/$key using only the standard library.

Go Playground: https://go.dev/play/p/d6PvbPjXQRE

package main

import (
	"net/http"
	"strings"
	"sync"
)

// simple http server that acts a key value store
func main() {
	// create the data store and the mutex
	// the mutex is used to synchronize access to the data store
	rwmutex := sync.RWMutex{}
	data := make(map[string]string)
	mux := http.NewServeMux()
	// register a handler for the "/set" path
	// example: curl localhost:8080/set/foo/bar will set the key "foo" to the value "bar"
	mux.HandleFunc("/set/", func(w http.ResponseWriter, r *http.Request) {
		// get the key and value from the path
		pathParts := strings.Split(r.URL.Path, "/")
		if len(pathParts) < 4 {
			w.WriteHeader(http.StatusBadRequest)
			return
		}
		key, value := pathParts[2], pathParts[3]
		// set the value in the data store
		rwmutex.Lock()
		data[key] = value
		rwmutex.Unlock()
		// return a 200 OK
		w.WriteHeader(http.StatusOK)
	})
	// register a handler for the "/get" path
	// example:  curl localhost:8080/get/foo will return the value for the key "foo"
	mux.HandleFunc("/get/", func(w http.ResponseWriter, r *http.Request) {
		// get the key from the path
		pathParts := strings.Split(r.URL.Path, "/")
		key := pathParts[2]
		// get the value from the data store
		rwmutex.RLock()
		value, ok := data[key]
		rwmutex.RUnlock()
		// if the key does not exist return a 404 not found
		if !ok {
			w.WriteHeader(http.StatusNotFound)
			return
		}
		// write the value to the response
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(value))
	})
	// start the http server
	println("starting server at :8080")
	if err := http.ListenAndServe(":8080", mux); err != nil {
		println(err)
	}
}

Using the code

$ go run http2.go
starting server at :8080
$ curl localhost:8080/set/foo/bar
$ curl localhost:8080/get/foo    
bar