stretchr / goweb Goto Github PK
View Code? Open in Web Editor NEWA lightweight RESTful web framework for Go
A lightweight RESTful web framework for Go
Hi,
I have a question.
Why Formatter.Format's return value is []uint8 but []byte?
http://godoc.org/github.com/stretchrcom/goweb/goweb#Formatter
encoding/json package and other encoding packges use []byte as type of serialized data.
This one comes from your front-end developers complaining (as usually) about support of all HTTP by some browsers. Does it makes sense to add these features to the API responder?
For example if I wanted to pass in stripe.com in a url like:
www.example.com/api/company/stripe.com/info
And listener was setup as such:
goweb.MapFunc("/api/company/{company}/info/", func(c *goweb.Context) {
fmt.Println(c.PathParams["company"])
}) //goweb.MapFunc
I get "stripe" printed out, instead of "stripe.com"
If use Controllers and set custom encoding, encoding don't work
Example:
goweb.MapBefore(func(c context.Context) error {
// add a custom header
c.HttpResponseWriter().Header().Set(`Content-Type`, `application/json; charset=UTF-8`)
return nil
})
Bugfix this:
File: goweb/responders/goweb_api_responders.go
@@ -118,7 +118,9 @@ func (a *GowebAPIResponder) WriteResponseObject(ctx context.Context, status int
Views are a key part of web development, and if you're not building a data API you will likely be managing views in some way within Goweb.
We would like to implement a solution for new projects that will make managing views as easy as it is in Ruby on Rails.
Initial thinking:
/controller/action
would map to the action
method on the controller
class. E.g. /people/new
would map to PeopleController
and call method New
.Something like this should work:
type Context interface { context.Context }
Trying to install latest goweb 7/8/2013 against latest commit 7310eb9
Here is the compilation output:
troy$ go get github.com/stretchr/goweb
github.com/stretchr/goweb/map.go:192: undefined: MatcherFunc
github.com/stretchr/goweb/map.go:206: undefined: MatcherFuncs
Adding "handlers." before MatcherFunc on line 192 fixes the compilation problem at line 192, but adding "handlers." before MatcherFuncs on line 206 doesn't fix the problem there:
troy$ go get github.com/stretchr/goweb
./map.go:206: undefined: handlers.MatcherFuncs
I have been able to build about 6 other packages with this latest version of go1.1.1, so I am pretty sure it is not a problem with my installation. If you want me to try to reproduce on Debian 7.1 I can give that a try once I get go installed on my new Debian VM.
Go 1.1 now implements method values, which are functions that have been bound to a specific receiver value. For instance, given a Writer value w, the expression w.Write, a method value, is a function that will always write to w; it is equivalent to a function literal closing over w:
func (p []byte) (n int, err error) {
return w.Write(p)
}
Method values are distinct from method expressions, which generate functions from methods of a given type; the method expression (_bufio.Writer).Write is equivalent to a function with an extra first argument, a receiver of type (_bufio.Writer):
func (w *bufio.Writer, p []byte) (n int, err error) {
return w.Write(p)
}
Updating: No existing code is affected; the change is strictly backward-compatible.
package github.com/ugorji/go-msgpack has been deprecated (05/29/2013).
It will be retired anytime from July 1, 2013.
Please update to faster and much much better github.com/ugorji/go/codec.
See https://github.com/ugorji/go/tree/master/codec#readme for more information.
It seems slightly odd that Map, MapBefore, and MapAfter all accept MatcherFuncs as additional parameters, while MapController, MapStaticFile, and MapStatic don't.
Use Case:
I am writing a RESTful API. I want a different controller to be called for different types of Accept headers. When the Accept header includes 'text/html', I want to display my generated godoc documentation (using MapStatic or MapStaticFile). When the Accept header includes 'application/-+', I want to run the an API controller that runs the correct version.
I want to do this by essentially passing a MatcherFunc to the MapController, MapStatic, etc methods which checks the Accept header against a list of acceptable values. But currently, they cannot accept MatcherFuncs.
I'm forking the repo and tossing that in myself (because it's easy), and ... will probably make a pull request after I get it working, because ... that's the right thing to do? I think? Goodness, I'm too used to bugzilla and attaching patches. I feel old.
[edit] If there's a better way to do this, please let me know. I haven't been doing this very long, but from what I've seen, that seems to be the best route. [/edit]
Currently, errors (like 404
or 500
) won't cause the callback to be triggered.
always200
parameter, is that the right approach again?Please leave a comment and tell us:
func main() {
goweb.MapFunc("/", func(c *goweb.Context) {
t, _ := template.ParseFiles("html/index.html")
t.Execute(c.ResponseWriter, nil)
})
goweb.MapFunc("/user", func(c *goweb.Context) {
fmt.Println(c.Request.FormValue("id"))
fmt.Println(c.Request.FormValue("pass"))
})
goweb.ListenAndServe(":8080")
}
root page is
"Oops, something went wrong: No route found for that path"
why not working?
my eye's in Red on inside every code
i don't know that.
help me
I finally got around to reading the documentation for goweb. Don't ask me why it's taken me this long.
I noticed the ?method=GET variable types in the documentation. I'm not planning to use it in my code, but it's kinda fun for testing stuff in the browser when I'm too lazy to alt+tab to my terminal and write out a curl request.
So I was wondering if we could get an equivalent for the Accept header. Seems like it would be nice for being able to read through XML vs JSON output and such.
Goweb should, by default, manage OPTIONS and HEAD operations.
I am having an issue such that MapFunc is matching anything with the sub string of the path. For example:
goweb.MapFunc("/a", serverA)
goweb.MapFunc("/nota", serverB)
And any page containing "a" will call serverA, including "localhost:8080/nota", and for example, "localhost:8080/ishouldbe404a" is also calling serveA.
We are looking to put together a list of companies / people that are using Goweb. If you would like to help promote Goweb, and be included in the list, please comment on this issue and we'll get it going.
Thanks,
Goweb team
It would be great to map a single file, instead of having to map an entire directory.
Use case:
Should be doable like this:
goweb.MapStaticFile("favicon.ico", "/static/files/images/icons/favicon.ico")
What I did is taking an example web-server and moving out the ThingsController into the ./controllers sub-package:
package controllers
import (
"github.com/stretchrcom/goweb"
"github.com/stretchrcom/goweb/context"
"net/http"
)
// ThingsController is the RESTful MVC controller for Things.
type ThingsController struct {
}
// Before gets called before any other method.
func (r *ThingsController) Before(ctx context.Context) error {
return nil
}
// After gets called before any other method.
func (r *ThingsController) After(ctx context.Context) error {
return nil
}
func (r *ThingsController) Create(ctx context.Context) error {
return goweb.Respond.WithStatus(ctx, http.StatusCreated)
}
func (r *ThingsController) ReadMany(ctx context.Context) error {
return goweb.API.RespondWithData(ctx, "DEMO!")
}
func (r *ThingsController) Read(id string, ctx context.Context) error {
return goweb.Respond.WithStatus(ctx, http.StatusNotFound)
}
func (r *ThingsController) DeleteMany(ctx context.Context) error {
return goweb.Respond.WithOK(ctx)
}
func (r *ThingsController) Delete(id string, ctx context.Context) error {
return goweb.Respond.WithOK(ctx)
}
Then mapped it using:
goweb.MapController("/api/things", new(controllers.ThingsController))
As a result:
Pipe 0:
*** - 0x35e0
Pipe 1:
/ - 0x3a50
OPTIONS /api/things - 0xe9240
OPTIONS /api/things/{id} - 0xe9340
*** - 0x3b20
Pipe 2:
*** - 0x36b0
The other REST methods are not mapped and requests return 404. Moving the code back into the same main.go makes things work again.
We will get a lot for free by implementing this properly.
e.g
controller.RestfulUpdaterMethod = "POST"
A simple REST controller with a method:
func (ctrl _MyController) ReadMany(ctx context.Context) error {
var Things []_Thing
thing := new(Thing)
thing.Id = "A"
thing.Text = "A Thing!"
Things = append(Things, thing)
return goweb.API.RespondWithData(ctx, Things)
}
Request: GET /api/my
Leads to the following in the console:
2013/06/12 10:53:32 http: panic serving 127.0.0.1:49779: codecs: Cannot call PublicData([]_controllers.Thing) because it does not implement codecs.Facade (i.e. needs PublicData method) and is not a Data object.
goroutine 11 [running]:
net/http.func·007()
/usr/local/go/src/pkg/net/http/server.go:1022 +0xac
github.com/stretchrcom/codecs.publicData(0x274fe0, 0xc200151c60, 0x0, 0x0, 0x6e7a30, ...)
/Users/alex/Documents/Work/sources/backend/src/github.com/stretchrcom/codecs/facade.go:106 +0x2fe
github.com/stretchrcom/codecs.PublicData(0x274fe0, 0xc200151c60, 0x0, 0x1, 0x2842a0, ...)
/Users/alex/Documents/Work/sources/backend/src/github.com/stretchrcom/codecs/facade.go:63 +0x42
github.com/stretchrcom/goweb/responders.(_GowebAPIResponder).Respond(0xc2000eb7e0, 0xc2000dc7e0, 0xc200157c40, 0xc8, 0x274fe0, ...)
/Users/alex/Documents/Work/sources/backend/src/github.com/stretchrcom/goweb/responders/goweb_api_responder.go:130 +0xa8
github.com/stretchrcom/goweb/responders.(_GowebAPIResponder).RespondWithData(0xc2000eb7e0, 0xc2000dc7e0, 0xc200157c40, 0x274fe0, 0xc200151c60, ...)
/Users/alex/Documents/Work/sources/backend/src/github.com/stretchrcom/goweb/responders/goweb_api_responder.go:155 +0x6c
project/api/controllers.(_MyController).ReadMany(0xc2000008a8, 0xc2000dc7e0, 0xc200157c40, 0x1, 0x1, ...)
/Users/alex/Documents/Work/sources/backend/src/project/api/controllers/poi.go:37 +0x171
github.com/stretchrcom/goweb/controllers.RestfulManyReader.ReadMany·fm(0xc2000dc7e0, 0xc200157c40, 0x0, 0x0)
/Users/alex/Documents/Work/sources/backend/src/github.com/stretchrcom/goweb/handlers/mapping.go:234 +0x52
github.com/stretchrcom/goweb/handlers.(_PathMatchHandler).Handle(0xc2000ebf00, 0xc2000dc7e0, 0xc200157c40, 0x1, 0x0, ...)
/Users/alex/Documents/Work/sources/backend/src/github.com/stretchrcom/goweb/handlers/path_match_handler.go:137 +0x38
github.com/stretchrcom/goweb/handlers.Pipe.Handle(0xc200100600, 0x17, 0x20, 0xc2000dc7e0, 0xc200157c40, ...)
/Users/alex/Documents/Work/sources/backend/src/github.com/stretchrcom/goweb/handlers/pipe.go:61 +0x121
github.com/stretchrcom/goweb/handlers.(_Pipe).Handle(0xc200151800, 0xc2000dc7e0, 0xc200157c40, 0xdd301, 0x0, ...)
/Users/alex/Documents/Work/sources/backend/src/github.com/stretchrcom/goweb/handlers/default_error_handler.go:0 +0x9a
github.com/stretchrcom/goweb/handlers.Pipe.Handle(0xc20014d690, 0x3, 0x3, 0xc2000dc7e0, 0xc200157c40, ...)
/Users/alex/Documents/Work/sources/backend/src/github.com/stretchrcom/goweb/handlers/pipe.go:61 +0x121
github.com/stretchrcom/goweb/handlers.(_HttpHandler).ServeHTTP(0xc2001468c0, 0xc2001544c0, 0xc200157bd0, 0xc20014b680)
/Users/alex/Documents/Work/sources/backend/src/github.com/stretchrcom/goweb/handlers/http_handler.go:67 +0xac
net/http.serverHandler.ServeHTTP(0xc200147820, 0xc2001544c0, 0xc200157bd0, 0xc20014b680)
/usr/local/go/src/pkg/net/http/server.go:1517 +0x16c
net/http.(_conn).serve(0xc2000e26c0)
/usr/local/go/src/pkg/net/http/server.go:1096 +0x765
created by net/http.(*Server).Serve
/usr/local/go/src/pkg/net/http/server.go:1564 +0x266
Having /something/[optional]/else currently works, but makes no sense. An optional segment should not be allowed to appear before a static segment.
For testing, it's nice to have services stored in the handler so it can be pulled out of the context.
I have a client app in a different domain so the browser is trying to do a preflight request. e.g.
OPTIONS /accounts HTTP/1.1
Host localhost:5000
Access-Control-Request-Method GET
Origin http://localhost:9000
Access-Control-Request-Headers accept, x-requested-with
Accept */*
Referer http://localhost:9000/
...
I would like goweb to generate the necessary response for any request coming for a particular url e.g.
Access-Control-Allow-Origin: http://localhost:9000
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf-8
Can you please give me an example on how to deal with this? Thanks
Add ability for controller to self map - so people can keep the mapping code inside the controller.
In the docs (http://godoc.org/github.com/stretchr/goweb/controllers#RestfulManyUpdater), the RestfulManyUpdater has this mapping:
GET /resources/{id}
Which is not correct and should instead be:
PUT /resources
I haven't check if it is only an error in documentation or if the implementation is incorrect also
Testing code (unit testing and other types) is very important, Goweb itself is 100% TDD, so we need to make sure we are not getting in the way of others from writing test-driven Goweb code.
So:
The catchall handler is always invoked, even if something has already been served.
This could be indicative of a deeper problem.
Since POST
should create resources, I propose we change the way Goweb maps the RESTful interfaces in the following way.
These will stay the same:
RestfulReader Read = GET /path/{id}
RestfulManyReader ReadMany = GET /path
RestfulCreator Create = POST /path
RestfulDeletor Delete = DELETE /path/{id}
RestfulManyDeleter DeleteMany = DELETE /path
(OPTIONS and HEAD will remain the same)
These will change from:
RestfulUpdater Update = PUT /path/{id}
RestfulReplacer Replace = POST /path/{id}
RestfulManyUpdater UpdateMany = PUT /path
to
RestfulUpdater Update = PATCH /path/{id}
RestfulReplacer Replace = PUT /path/{id}
RestfulManyUpdater UpdateMany = PATCH /path
Maybe as a MatcherFunc
goweb.Map(func(context.Context) error {}, goweb.RegexPath("THEREGEX"))
Making a hyphenated URL request causes the GET parameters to contain a trailing '?'.
For instance, if I make the call:
http://localhost/api/1/company/board-members/?ids=106,104
I get ids = 106,104?
The Goweb API responder can have all the stuff one it - but the interface should be cleaner.
I am trying to send some JSON data to a GET request. The body is empty, even though I am transmitting some. It works fine for POST actions
EDIT:
Seems to be working now. I think it was whatever tool I was using to send the request
Currently JSON is hard coded into Goweb... but the http://github.com/stretchrcom/codecs package supports a content negotiation system, so we should use that.
// AllQueryParams gets the parameters that were present after the ? in the URL.
QueryParams() objects.Map
// QueryValues gets an array of the values for the specified key from the QueryParams.
QueryValues(key string) []string
// QueryValue gets a single value for the specified key from the QueryParams. If there
// are multiple values (i.e. `?name=Mat&name=Laurie`), the first value is returned.
QueryValue(key string) string
This could be a good example:
http://www.gorillatoolkit.org/pkg/context
Thus in the request handling chain (Before -> Controller's Method -> After) it would be really easy to share the data.
As an example we use:
This would help to avoid duplication of code especially related to authentication...
Will you be adding support for PATCH
?
HI,
maybe I'm missing something but I can't find any obvious way to turn off enveloping of data in responses (http://godoc.org/github.com/stretchr/goweb/responders#pkg-constants)
Data enveloping should not be default (http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#envelope) but rather let the API creator decide whether to support it or not.
Should the Goweb import path include the version number?
i.e.
import (
"github.com/stretchrcom/goweb/v2"
)
The namespace would still be goweb
allowing clean code.
Allow wildcard prefixes in paths.
We should also add convenience methods for the various other forms of redirect
Defining Before
and After
in a controller class should cause these methods to be mapped appropriately.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.