Golang URL Encoding and Decoding

URLs (Uniform Resource Locators) can only contain a limited set of characters from the US-ASCII character set. These characters include digits (0-9), letters(A-Z, a-z), and a few special characters (-, ., _, ~). Any character outside of this character set needs to be encoded or escaped before it can be used inside a URL.

In this article, you’ll learn how to encode a string so that it can be safely placed inside a URL.

URL Encoding or Escaping a String in Go

A URL consists of multiple parts (Host segment, Path segment, Query string, etc). The generic syntax looks like this

scheme:[//[user:password@]host[:port]]path[?query][#fragment]

Go provides the following two functions to encode or escape a string so that it can be safely placed inside a URL:

  • QueryEscape(): Encode a string to be safely placed inside a URL query string.
  • PathEscape(): Encode a string to be safely placed inside a URL path segment.

Let’s look at an example -

package main

import (
	"fmt"
	"net/url"
)

func main() {
	// QueryEscape: Escape a string to safely place it inside a URL query string
	str := "Gol@ng?&"
	encodedStr := url.QueryEscape(str)

	fmt.Println(encodedStr)

	// PathEscape: Escape a string to safely place it inside a URL path segment
	pathVar := "Gol@ng?&"
	encodedPathVar := url.PathEscape(pathVar)
	fmt.Println(encodedPathVar)
}
# Output
Gol%40ng%3F%26
Gol@ng%3F&

Decode/Unescape a URL encoded String in Go

To decode a URL encoded string back to the original form, you can use the QueryUnescape() and PathUnescape() functions. Here is an example demonstrating how to use these functions -

package main

import (
	"fmt"
	"net/url"
)

func main() {
	// QueryUnescape: Decode a URL query string
	encodedStr := "Gol%40ng%3F%26"
	decodedStr, err := url.QueryUnescape(encodedStr)
	if err != nil {
		fmt.Printf("Error decoding the string %v", err)
	}

	fmt.Println(decodedStr)

	// PathUnescape: Decode a URL path segment
	encodedPathVar := "Gol@ng%3F&"
	decodedPathVar, err := url.PathUnescape(encodedPathVar)
	if err != nil {
		fmt.Printf("Error decoding the string %v", err)
	}
	fmt.Println(decodedPathVar)
}
# Output
Gol@ng?&
Gol@ng?&