Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fc augment request #18

Closed
wants to merge 3 commits into from

2 participants

@franckcuny

A few changes to the existing API (everything is subject to discussion of course :)

franckcuny added some commits
@franckcuny franckcuny 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).
98ee9e7
@franckcuny franckcuny Create a router using the new functions from the router.
Create a router by calling `NewRouter` and add routes using the function `AddRoute`.
fe75eca
@franckcuny franckcuny Add the function `Start` to the handler to start the HTTP server. fdbb7c0
@ant0ine
Owner

I don't think that a Handler should have a start method. This is the responsibility of the http.Server object. (This ResourceHandler can be wrapped into other Handlers, like SPDY for instance.) The examples use http.ListenAndServe, but the user can also chose to instantiate a custom http.Server object. We may want to provide a Server object that wraps http.Server, but that seems to be a lot of work and complexity just to print this info line.

@ant0ine
Owner

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
Owner

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

@ant0ine
Owner

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()

@ant0ine
Owner

oops, I've changed this implementation recently, that will require a rebase.

@franckcuny franckcuny closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 6, 2013
  1. @franckcuny

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

    franckcuny authored
    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).
  2. @franckcuny

    Create a router using the new functions from the router.

    franckcuny authored
    Create a router by calling `NewRouter` and add routes using the function `AddRoute`.
  3. @franckcuny
This page is out of date. Refresh to see the latest.
Showing with 61 additions and 22 deletions.
  1. +6 −2 examples/simple/main.go
  2. +19 −20 handler.go
  3. +36 −0 request.go
View
8 examples/simple/main.go
@@ -2,7 +2,6 @@ package main
import (
"github.com/ant0ine/go-json-rest"
- "net/http"
)
type User struct {
@@ -10,6 +9,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,7 +24,8 @@ 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)
+ handler.Start(":8080")
}
View
39 handler.go
@@ -12,7 +12,6 @@
//
// import (
// "github.com/ant0ine/go-json-rest"
-// "net/http"
// )
//
// type User struct {
@@ -33,7 +32,7 @@
// handler.SetRoutes(
// rest.Route{"GET", "/users/:id", GetUser},
// )
-// http.ListenAndServe(":8080", &handler)
+// handler.Start(":8080")
// }
//
package rest
@@ -129,40 +128,40 @@ func RouteObjectMethod(httpMethod string, pathExp string, objectInstance interfa
// if a request matches multiple Routes, the first one will be used.
// Note that the underlying router is https://github.com/ant0ine/go-urlrouter.
func (self *ResourceHandler) SetRoutes(routes ...Route) error {
- self.router = urlrouter.Router{
- Routes: []urlrouter.Route{},
- }
+ self.router = urlrouter.NewRouter()
for _, route := range routes {
// make sure the method is uppercase
httpMethod := strings.ToUpper(route.HttpMethod)
- self.router.Routes = append(
- self.router.Routes,
- urlrouter.Route{
- PathExp: httpMethod + route.PathExp,
- Dest: route.Func,
- },
- )
+ error := self.router.AddRoute(urlrouter.Route{
+ PathExp: httpMethod + route.PathExp,
+ Dest: route.Func,
+ })
+ if error != nil {
+ panic(error)
+ }
}
// add the status route as the last route.
if self.EnableStatusService == true {
self.statusService = newStatusService()
- self.router.Routes = append(
- self.router.Routes,
- urlrouter.Route{
- PathExp: "GET/.status",
- Dest: func(w *ResponseWriter, r *Request) {
- self.statusService.getStatus(w, r)
- },
+ self.router.AddRoute(urlrouter.Route{
+ PathExp: "GET/.status",
+ Dest: func(w *ResponseWriter, r *Request) {
+ self.statusService.getStatus(w, r)
},
- )
+ })
}
return self.router.Start()
}
+func (self *ResourceHandler) Start(port string) {
+ fmt.Println(fmt.Sprintf("== Starting the server, listening on %s", port))
+ http.ListenAndServe(port, self)
+}
+
type responseLogRecord struct {
StatusCode int
ResponseTime *time.Duration
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("/$")
+ 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 {
+ query := url.Values{}
+ for k, v := range parameters {
+ query.Add(k, v)
+ }
+ url := fmt.Sprintf("%s?%s", self.UriFor(path), query.Encode())
+ return url
+}
Something went wrong with that request. Please try again.