Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add a few convenient functions for URL to the Request type.

The three added functions allow an easier creation of URLs.  This can be
useful when, in the application, the developer need to generate an
absolute URL (e.g.: for a redirect, to link to a resource, etc).
  • Loading branch information...
commit 98ee9e7b34592144c1dbb9139041299ef2cc7d13 1 parent fdadeb5
@franckcuny authored
Showing with 41 additions and 0 deletions.
  1. +5 −0 examples/simple/main.go
  2. +36 −0 request.go
View
5 examples/simple/main.go
@@ -10,6 +10,10 @@ type User struct {
Name string
}
+func GetOldAPIUser(w *rest.ResponseWriter, req *rest.Request) {
+ http.Redirect(w, req.Request, req.UriFor("/users/1"), 302)
+}
+
func GetUser(w *rest.ResponseWriter, req *rest.Request) {
user := User{
Id: req.PathParam("id"),
@@ -21,6 +25,7 @@ func GetUser(w *rest.ResponseWriter, req *rest.Request) {
func main() {
handler := rest.ResourceHandler{}
handler.SetRoutes(
+ rest.Route{"GET", "/user/:id", GetOldAPIUser},
rest.Route{"GET", "/users/:id", GetUser},
)
http.ListenAndServe(":8080", &handler)
View
36 request.go
@@ -2,8 +2,11 @@ package rest
import (
"encoding/json"
+ "fmt"
"io/ioutil"
"net/http"
+ "net/url"
+ "regexp"
)
// Inherit from http.Request, and provide additional methods.
@@ -31,3 +34,36 @@ func (self *Request) DecodeJsonPayload(v interface{}) error {
}
return nil
}
+
+// Returns an absolute URI for the base (scheme + host) of the application,
+// without the trailing slash.
+func (self *Request) UriBase() string {
+ scheme := self.URL.Scheme
+ if scheme == "" {
+ scheme = "http"
+ }
+
+ url := fmt.Sprintf("%s://%s", scheme, self.Host)
+
+ trailingSlash, _ := regexp.Compile("/$")
@ant0ine
ant0ine added a note

I have the habit to put regexp everywhere too, but in case like this one, I try to just check the last char of the string. I think that's more efficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ if trailingSlash.MatchString(url) == true {
+ url = trailingSlash.ReplaceAllString(url, "")
+ }
+ return url
+}
+
+// Returns an URI from the base and path.
+func (self *Request) UriFor(path string) string {
+ url := fmt.Sprintf("%s%s", self.UriBase(), path)
+ return url
+}
+
+// Returns an URI from the base, the path, and the parameters.
+func (self *Request) UriForWithParams(path string, parameters map[string]string) string {
@ant0ine
ant0ine added a note

map[string]string is an approximation, we could have an array of values for a key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ query := url.Values{}
+ for k, v := range parameters {
+ query.Add(k, v)
+ }
+ url := fmt.Sprintf("%s?%s", self.UriFor(path), query.Encode())
+ return url
+}

1 comment on commit 98ee9e7

@ant0ine

I have the habit to put regexp everywhere too, but in case like this one, I try to just check the last char of the string. I think that's more efficient.

@ant0ine

map[string]string is an approximation, we could have an array of values for a key.

@ant0ine

I see the need for these kind of methods. This is definitely something to add to the requirements. Basically, help the user to build URLs.
But I'm thinking that maybe these methods should return url.URL object. These methods would just "edit" the url.URL, the caller would get the string with URL.String()

Please sign in to comment.
Something went wrong with that request. Please try again.