見出し画像

Golang_net/urlパッケージを使う #478

Go言語には、URLを操作するための便利なパッケージであるnet/urlが用意されています。文字列からURLを読み取って、ホスト部分やパラメータ部分を切り出して操作することが可能です。

業務でこのパッケージを扱うことがあったので、この機会にまとめてみます。

url.URLとは

URLを構成する各要素(スキーム、ホスト、パス、クエリパラメータなど)を個別に操作できる構造体です。この構造体を利用することで、URLの解析、生成、操作が簡単に行えます。

基本的な使い方

URLの文字列をParse()メソッドにかけた後、簡単にいろんな操作ができます。

package main
 
import (
    "fmt"
    "net/url"
)
 
func main() {
    rawURL := "https://example.com:8080/path?foo=bar#section"
 
    u, err := url.Parse(rawURL)
    if err != nil {
        fmt.Println("Error: ", err)
        return
    }
 
    fmt.Println("Schema: ", u.Schema)
    fmt.Println("Host: ", u.Host)
    fmt.Println("Path: ", u.Path)
    fmt.Println("RawQuery: ", u.RawQuery)
    fmt.Println("Fragment: ", u.Fragment)
}

上記を実行すると次のような出力が得られます。

Scheme: https
Host: example.com:8080
Path: /path
RawQuery: foo=bar
Fragment: section

url.URLの代表的なメソッド

以下のような便利なメソッドを持っています。

Parse:
先ほどの例でも使用した、URLの形をした文字列を解析してurl.URL構造体を返します。

u, err := url.Parse("https://example.com/path?foo=bar#section")
if err != nil {
	fmt.Println("Error:", err)
}

String:
url.URL構造体を文字列として表現します。

fmt.Println(u.String())  // https://example.com/path?foo=bar#section

Query:
URLのクエリパラメータを解析してurl.Valuesというマップ形式の構造体を返します。

query := u.Query()
fmt.Println(query.Get("foo"))  // bar
 
query.Set("newkey", "value")
fmt.Println(query.Encode())  // foo=bar&newkey=value

ResoleveReference:
相対URLを基準URLに連結(解決)できます。パスを動的に作成したい場合などに使えそうです。

base, _ := url.Parse("https://example.com/path/")
ref, _ := url.Parse("subpath?foo=bar")
resolved := base.ResoleveReference(ref)
fmt.Println(resolved.String()) // https://example.com/path/subpath?foo=bar

HostnameとPort:
Hostnameメソッドは、ポートを含まないホスト名を返し、Portメソッドはポート番号を返します。

fmt.Println(u.Hostname()) // example.com
fmt.Println(u.Port())     // 8080

PathEscapeとPathUnescape:
パスをエスケープ処理するためのメソッドです。

escaped := url.PathEscape("/path with spaces")
fmt.Println(escaped) // /path%20with%20spaces

unescaped, _ := url.PathUnescape(escaped)
fmt.Println(unescaped) // /path with spaces

QueryEscapeとQueryUnescape:
クエリパラメータをエスケープ処理するメソッドもあります。

escapedQuery := url.QueryEscape("foo=bar&baz=qux")
fmt.Println(escapedQuery) // foo%3Dbar%26baz%3Dqux

unescapedQuery, _ := url.QueryUnescape(escapedQuery)
fmt.Println(unescapedQuery) // foo=bar&baz=qux


url.Valuesを使ったクエリパラメータの作成

url.Valuesはurl.URL.Query()で使用したマップ構造です。これを利用して新しいクエリパラメータを作成できます。

既存のURLに新しいクエリパラメータを追加する方法を見てみます。

package main

import (
    "fmt"
    "net/url"
)

func main() {
    // クエリパラメータの設定
    params := url.Values{}
    params.Set("foo", "bar")
    params.Set("baz", "qux")

    // クエリパラメータをエンコードして文字列として扱う準備
    encodedParams := params.Encode()
    fmt.Println(encodedParams)  // foo=bar&baz=qux

    // URLにクエリパラメータを追加
    baseURL := "https://example.com/path"
	fullURL := baseURL + "?" + encodedParams
	fmt.Println(fullURL) // https://example.com/path?foo=bar&baz=qux
}
 

単純にクエリパラメータをセットするだけなら元のURLでQuery()メソッドを使って、そのurl.Values構造体のSet()メソッドで追加すれば済みます。

ただ上記のようにurl.Values{} を新たに使えば、元々のクエリパラメータがイレギュラーな形式をしている場合など、柔軟にURLを調整できます。


ここまでお読みいただきありがとうございました!


この記事が気に入ったらサポートをしてみませんか?