Url Parsing in Clojure

Here’s the translation of the URL parsing example from Go to Clojure, formatted in Markdown suitable for Hugo:

Our URL parsing program demonstrates how to parse and extract different components from a URL string in Clojure.

(ns url-parsing
  (:require [clojure.string :as str])
  (:import (java.net URI)))

(defn main []
  ; We'll parse this example URL, which includes a
  ; scheme, authentication info, host, port, path,
  ; query params, and query fragment.
  (let [s "postgres://user:pass@host.com:5432/path?k=v#f"
        ; Parse the URL and ensure there are no errors.
        uri (URI. s)]
    
    ; Accessing the scheme is straightforward.
    (println (.getScheme uri))
    
    ; userInfo contains all authentication info
    (let [user-info (.getUserInfo uri)]
      (println user-info)
      (when user-info
        (let [[username password] (str/split user-info #":")]
          (println username)
          (println password))))
    
    ; The Host contains both the hostname and the port,
    ; if present. We can extract them separately.
    (println (.getHost uri))
    (println (.getPort uri))
    
    ; Here we extract the path and the fragment after
    ; the #.
    (println (.getPath uri))
    (println (.getFragment uri))
    
    ; To get query params in a string of k=v format,
    ; use getRawQuery. You can also parse query params
    ; into a map.
    (println (.getRawQuery uri))
    (let [query (.getQuery uri)
          params (when query
                   (into {}
                         (for [param (str/split query #"&")]
                           (str/split param #"="))))]
      (println params)
      (println (get params "k")))))

(main)

Running our URL parsing program shows all the different pieces that we extracted:

$ clj url_parsing.clj
postgres
user:pass
user
pass
host.com
5432
/path
f
k=v
{"k" "v"}
v

In this Clojure version:

  1. We use the java.net.URI class to parse the URL, which provides similar functionality to Go’s url.Parse.
  2. We extract the various components of the URL using methods on the URI object.
  3. For parsing the query string into a map, we implement a simple parsing function using Clojure’s string manipulation functions.
  4. The overall structure and flow of the program remain similar to the original Go version, demonstrating the same URL parsing concepts.

Note that Clojure, being a JVM language, leverages Java’s built-in URI parsing capabilities. This approach might differ slightly from Go’s implementation but achieves the same result of parsing and extracting URL components.