josephkibe
josephkibe

Reputation: 1343

Is there a more canonical way to manipulate a URL path in Go?

I'm working on a system in Go to act as middleware. For some of our URLs in other services that I want to parse and analyze, we've embedded something variable at the beginning of the path.

For instance, imagine for user amysmith we might have the path /amysmith/edit/profile to edit the user profile of amysmith.

For the purposes of this system, I'd like to swap the path to become /edit/profile, as if the first part of the path weren't there. Admittedly, this is not ideal, but changing that overall naming is a bigger project for another time.

This is achievable by using strings.Join and then prepending a / and lopping off the last character. I'd like to do this because it keeps the path format in line with other paths that aren't manipulated, which will always begin with a /.

func (r Resource) CleanedPath() string {
    parts := strings.Split(r.URL.Path, "/")
    return strings.TrimRight("/" + strings.Join(parts[2:], "/"), "/")
}

That approach feels a bit clunky to me. Is there a better more "Go" way to do this?

Upvotes: 1

Views: 991

Answers (2)

Zombo
Zombo

Reputation: 1

Here is a method that uses no packages:

package main

func split(path string, count int) string {
   for n, r := range path {
      if r == '/' { count-- }
      if count == 0 {
         return path[n:]
      }
   }
   return ""
}

func main() {
   { // example 1
      s := split("/amysmith/edit/profile", 2)
      println(s == "/edit/profile")
   }
   { // example 2
      s := split("/amysmith/edit/profile", 3)
      println(s == "/profile")
   }
}

Upvotes: 2

user13631587
user13631587

Reputation:

Chop off everything before the second /.

func cleanPath(p string) string {
    if i := strings.IndexByte(p[len("/"):], '/'); i >= 0 {
        return p[i+len("/"):]
    }
    return p
}

This approach avoids memory allocations.

Upvotes: 5

Related Questions