Giter VIP home page Giter VIP logo

go-restful's Introduction

go-restful

package for building REST-style Web Services using Google Go

Go Report Card GoDoc codecov

REST asks developers to use HTTP methods explicitly and in a way that's consistent with the protocol definition. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods. According to this mapping:

  • GET = Retrieve a representation of a resource
  • POST = Create if you are sending content to the server to create a subordinate of the specified resource collection, using some server-side algorithm.
  • PUT = Create if you are sending the full content of the specified resource (URI).
  • PUT = Update if you are updating the full content of the specified resource.
  • DELETE = Delete if you are requesting the server to delete the resource
  • PATCH = Update partial content of a resource
  • OPTIONS = Get information about the communication options for the request URI

Usage

Without Go Modules

All versions up to v2.*.* (on the master) are not supporting Go modules.

import (
	restful "github.com/emicklei/go-restful"
)

Using Go Modules

As of version v3.0.0 (on the v3 branch), this package supports Go modules.

import (
	restful "github.com/emicklei/go-restful/v3"
)

Example

ws := new(restful.WebService)
ws.
	Path("/users").
	Consumes(restful.MIME_XML, restful.MIME_JSON).
	Produces(restful.MIME_JSON, restful.MIME_XML)

ws.Route(ws.GET("/{user-id}").To(u.findUser).
	Doc("get a user").
	Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")).
	Writes(User{}))		
...
	
func (u UserResource) findUser(request *restful.Request, response *restful.Response) {
	id := request.PathParameter("user-id")
	...
}

Full API of a UserResource

Features

  • Routes for request → function mapping with path parameter (e.g. {id} but also prefix_{var} and {var}_suffix) support
  • Configurable router:
    • (default) Fast routing algorithm that allows static elements, google custom method, regular expressions and dynamic parameters in the URL path (e.g. /resource/name:customVerb, /meetings/{id} or /static/{subpath:*})
    • Routing algorithm after JSR311 that is implemented using (but does not accept) regular expressions
  • Request API for reading structs from JSON/XML and accessing parameters (path,query,header)
  • Response API for writing structs to JSON/XML and setting headers
  • Customizable encoding using EntityReaderWriter registration
  • Filters for intercepting the request → response flow on Service or Route level
  • Request-scoped variables using attributes
  • Containers for WebServices on different HTTP endpoints
  • Content encoding (gzip,deflate) of request and response payloads
  • Automatic responses on OPTIONS (using a filter)
  • Automatic CORS request handling (using a filter)
  • API declaration for Swagger UI (go-restful-openapi)
  • Panic recovery to produce HTTP 500, customizable using RecoverHandler(...)
  • Route errors produce HTTP 404/405/406/415 errors, customizable using ServiceErrorHandler(...)
  • Configurable (trace) logging
  • Customizable gzip/deflate readers and writers using CompressorProvider registration
  • Inject your own http.Handler using the HttpMiddlewareHandlerToFilter function

How to customize

There are several hooks to customize the behavior of the go-restful package.

  • Router algorithm
  • Panic recovery
  • JSON decoder
  • Trace logging
  • Compression
  • Encoders for other serializers
  • Use the package variable TrimRightSlashEnabled (default true) to control the behavior of matching routes that end with a slash /

Resources

Type git shortlog -s for a full list of contributors.

© 2012 - 2023, http://ernestmicklei.com. MIT License. Contributions are welcome.

go-restful's People

Contributors

andronat avatar bailantaotao avatar bartcpostma avatar brendandburns avatar ddysher avatar dkolbly avatar emicklei avatar erraggy avatar gitdr avatar guymorgan avatar iainduncani avatar ivanhawkes avatar jchenry avatar m0sth8 avatar manbeardo avatar mbohlool avatar mei-rune avatar moddus avatar mtojek avatar nikhiljindal avatar nullbus avatar schleppy avatar smarterclayton avatar spring1843 avatar thesyncim avatar tiwoc avatar tmc avatar viblo avatar vikstrous avatar wuub avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-restful's Issues

Produces(restful.MIME_JSON) Not Returning "application/json" as Content-Type

I've been using go-restful for a few weeks and so far have been really impressed. I'm having one issue that I can not figure out. (Go newbie here)

I have created a WebService specifying it Consumes and Produces JSON, however the response I receive from the server has the Content-Type as "text/plain".

I have read and re-read the documentation and can't solve this issue. I have tried adding an Accept header to the Request but "text/plain" is still returned. The documentation seems implies that if Produces set to only product JSON all responses from the server will have the Content-Type as "application/json"

Any ideas how to solve this issue?

ws := new(restful.WebService)
        ws.Path("/internal")
        ws.Consumes(restful.MIME_JSON)
        ws.Produces(restful.MIME_JSON)

        ws.Route(ws.GET("/category/{user_id}").To(r.getCategories).
                Doc("Return available categories").
                Param(ws.PathParameter("user_id", "Id of user").Required(true)).
                Writes(model.ApiResponse{}))

My handler function return the results as follows.

func (r MyResource) getCategories(req *restful.Request, resp *restful.Response) {
        ...
        resp.WriteHeader(http.StatusOK)
        resp.WriteAsJson(data)
        return
}

when i run go build in the go-restful dir ,err

just run go build,here is the log ,anything wrong ?

leotekiMacBook-Pro:go-restful leo$ go build

_/Users/leo/Downloads/go-restful

./container.go:64: method c.dispatch is not an expression, must be called
./container.go:76: method c.dispatch is not an expression, must be called
./container.go:78: method c.dispatch is not an expression, must be called

why use postman test error?

'''go lang
ws.Route(ws.PUT("").To(u.createUser).
Doc("create user").
Param(ws.BodyParameter("User", "User").DataType("User")).
Reads(model.User{})) // from the request

func (u *UserService) createUser(request *restful.Request, response *restful.Response) {
usr := new(model.User)
err := request.ReadEntity(&usr)
if err == nil {
_, err = u.UserLogic.SaveUser(usr)
log.Println(err)
} else {
log.Println("Create user err:", err)
}
}
'''
when I use swagger put data test is ok
when I use chrome rest console tool test is ok
but use chrome postman test report error:
415: Unsupported Media Type

Bug?

I define a struct File include file array.Cpu and memory is 100% when run this program.

I find if File struct not include []File the program is right.But I can't find proberlem point :(

type File struct {
    Id, Name   string
    HitoryFile []File
}

type FileService struct {
    // normally one would use DAO (data access object)
    files map[string]File
}

func (f FileService) Register() {
    ws := new(restful.WebService)
    ws.
        Path("/files").
        Consumes(restful.MIME_XML, restful.MIME_JSON).
        Produces(restful.MIME_JSON, restful.MIME_XML) // you can specify this per route as well

    ws.Route(ws.GET("/{file-id}").To(f.findFile).
        // docs
        Doc("get a file").
        Param(ws.PathParameter("file-id", "identifier of the file").DataType("string")).
        Writes(File{})) // on the response
    restful.Add(ws)
}

// GET http://localhost:8080/users/1
//
func (f FileService) findFile(request *restful.Request, response *restful.Response) {
    id := request.PathParameter("file-id")
    file := f.files[id]
    if len(file.Id) == 0 {
        response.WriteErrorString(http.StatusNotFound, "File could not be found.")
    } else {
        response.WriteEntity(file)
    }
}

func main() {
    f := FileService{map[string]File{}}
    f.Register()

    // Optionally, you can install the Swagger Service which provides a nice Web UI on your REST API
    // You need to download the Swagger HTML5 assets and change the FilePath location in the config below.
    // Open http://localhost:8080/apidocs and enter http://localhost:8080/apidocs.json in the api input field.
    config := swagger.Config{
        WebServices:    restful.RegisteredWebServices(), // you control what services are visible
        WebServicesUrl: "http://localhost:8080",
        ApiPath:        "/apidocs.json",

        // Optionally, specifiy where the UI is located
        SwaggerPath:     "/apidocs/",
        SwaggerFilePath: "./apiview"}
    swagger.InstallSwaggerService(config)

    log.Printf("start listening on localhost:8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Unexpected result in "restful-basic-authentication.go"

Hi,

I'm really new to GoLang and really found your efforts helpful.

I probably found a bug in "restful-basic-authentication.go".

In line:19

if len(encoded) == 0 || "YWRzOmFzZA==" != encoded 

Since the encoding method is BASE64, and the decoding of "YWRzOmFzZA==" is "ads:asd".

I think line:19 shoud be

if len(encoded) == 0 || "Basic YWRtaW4vYWRtaW4=" != encoded

Perhaps it could save others time who can't run this example.

Regards,
Leo

Can functions in "web_service_container.go" are encapsulated in a struct, it helpful for unit test

Can functions in "web_service_container.go" are encapsulated in a struct, it helpful for unit test, examples as:

func Test1(t *testing.T) {
   webContainer  := restful.NewContainer()
   ws := new(restful.WebService)
    .....
   webContainer.Add(ws)
    restful.WebContainer = webContainer
   ts := httptest.NewServer(restful.Dispatch)
   defer ts.Close()

  ......
}


func Test2(t *testing.T) {
   webContainer  := restful.NewContainer()
   ws := new(restful.WebService)
    .....
   webContainer.Add(ws)
    restful.WebContainer = webContainer
   ts := httptest.NewServer(restful.Dispatch)
   defer ts.Close()
  ......
}

Empty path parameter and avoiding 405 status code

This is truly a support question, sorry for abusing GH for this. I was wondering how to specify that a certain parameter "subset" can be not set.

Snippet of route definition is:

ws.Route(ws.GET("/datasets/taxonomy/{which}/{subset}").To(an.GetTaxonomyDatasets).
    Doc("blah").
    Param(ws.PathParameter("which", "blah")).
    Param(ws.PathParameter("subset", "blah").Required(false)).
    Writes(struct{ Datasets []Dataset }{}))

When calling this Route like

"...datasets/taxonomy/location/New York" it works, when calling like
"...datasets/taxonomy/location/" (There are locations with len(str) = 0) I get an

HTTP/1.1 405 Method Not Allowed
error.

Router returns 405: Method Not Allowed

My project setup has the base dir, then a dir/package for "model" and a dir/package for "services". I have a user.go file in "services" that handles registration for the users service. This is the code for initializing the user service:

func NewUserService() *restful.WebService {
    webService := new(restful.WebService)
    webService.Path("/users").
        Consumes(restful.MIME_JSON).
        Produces(restful.MIME_JSON)

    webService.Route(webService.GET("/{id}").To(GetUser))
    webService.Route(webService.POST("/{id}/device").To(RegisterDevice))
    webService.Route(webService.POST("/{id}/changePassword").To(ChangePassword))

    webService.Route(webService.POST("/login").To(Login))

    return webService
}

Anytime I try to hit /login with a POST while running locally, I get a 405: Method Not Allowed response. Meanwhile, doing a POST to the other 2 endpoints works just fine. And on top of that, if I modify the route to be "/{somePathParam}/login", it works just fine.

How can use route path

func (u UserService) Register() {
    ws := new(restful.WebService)
    ws.
        Path("/users").
        Consumes(restful.MIME_XML, restful.MIME_JSON).
        Produces(restful.MIME_JSON, restful.MIME_XML) 

    ws.Route(ws.GET("/login").To(u.loginUser).
        Doc("get a user").
        Param(ws.QueryParameter("name", "username").DataType("string")).
        Param(ws.QueryParameter("pwd", "password").DataType("string")))
         //get all user service
         //get all team user service
         //get all user without password service .....

    ws.Route(ws.GET("/{user-id}").To(u.findUser).
        // docs
        Doc("get a user").
        Param(ws.PathParameter("user-id", "identifier of the user").DataType("string"))) 

    restful.Add(ws)
}

func (u UserService) loginUser(request *restful.Request, response *restful.Response) {
    log.Println("========================================")
    log.Println(request.QueryParameter("name"))
    log.Println(request.QueryParameter("pwd"))
}

func (u UserService) findUser(request *restful.Request, response *restful.Response) {
    id := request.PathParameter("user-id")
    log.Println("000000000000000000000000000000000000000000000000000")
    log.Println(id)
}

When i call findUser function result:
2013/08/14 14:17:33 000000000000000000000000000000000000000000000000000
2013/08/14 14:17:33 asdfasdfasd

When i call loginUser function result:
2013/08/14 14:17:41 000000000000000000000000000000000000000000000000000
2013/08/14 14:17:41 login

how can i create like http:/petstore.swagger.wordnik.com user service?

Accessing the HTTP Status Code in a FilterFunction.

I am implementing a global logging filter similar to one in your examples. What I can't figure out is how to log the Status Code of the response. restful.Response is composed of a http.ResponseWriter, there is no method to access the status code once the code is written using WriterHeader(code).

type Response struct { http.ResponseWriter accept string // content-types what the Http Request says it want to receive produces []string // content-types what the Route says it can produce }

This problem has been talked about on the Go mailing list and the solution is to wrap http.ResponseWriter (like you are doing!) and add an additional field to store the status code. Would you consider adding a field here to store that status code?

Thanks!

Produces(restful.MIME_JSON) but receive XML output

func NewMovieService() *restful.WebService {
    ws := new(restful.WebService)
    ws.Path("/api/v2/movies").
        Consumes(restful.MIME_JSON).
        Produces(restful.MIME_JSON)

    ws.Route(ws.GET("").To(getAllMovies).
        Doc("get all movies"))

    ws.Route(ws.GET("/{id}").To(getMovie).
        Doc("get a movie by its id").
        Param(ws.PathParameter("id", "movie id")))

    return ws
}

If I request /api/v2/movies from my browser I receive:

<?xml version="1.0" encoding="UTF-8"?>

 <File>
  <Id>1</Id>
  <Path>/media/data/media/movies/1 Harold.&amp;.Kumar.Go.To.White.Castle.2004.avi</Path>
  <SearchString>1 Harold &amp; Kumar Go To White Castle 2004</SearchString>
 </File>

[...]

can you add gzip ?

when i request from client with a gzip header, it can return gzip data

Any way to avoid registering on root '/' ?

Is there a way to register restful's handlers on something other than '/'? For example having restful attach to '/api/' so that I can serve a UI from '/'?

Or is the recommended route to run the webservice on another port and then reverse proxy from ':80/api/' -> ':8080/' ?

Passing additional data through FilterFunctions

I'm building a service that will require client authentication on request. Ideally I'd like to be able to validate the user id, query for the user, authenticate and then pass the user object down the chain so each layer doesn't have to re-query.

I think the best description of what I want to do is having a context that can be passed in addition to the request and response.

Is there some mechanism today that can support this?

func authenticateUserFilter(req *restful.Request, resp *restful.Response, chain *restful.FilterChain, context *restful.FilterContext) {  
   //Validate User Id

   // Query User from DB
   user, err := LoadFromDB()
   if err != nil {
       //Forbidden
   }
   context.Add("user", user)
   chain.ProcessFilter(req, resp, context)
}

How do I set Nickname?

I think it is really a mandatory swagger element and although my service work fine without it consuming clients probably needs the nickname.

Would something like this make sense:

.....Doc("Create or update the Application node").Nick("myCrudMethod")....?

405 on Options

I am attempting to OPTIONS on a valid web service resource, and it returns a 405.

Serving static files

Hello,

in order to be able to use the go-restful server more generally we need not only to execute rest commands but also be able to serve static files in a simple manner.

Do you plan to add this feature?

Best regards
Xavier

Configurable/wrappable Dispatch

I was looking for a nice way of logging every request but it seems like the explicit calls to http.HandlerFunc (providing it Dispatch) make this a bit tough.

How to enable CORS

in net/http I would do the following:

if origin := req.Header.Get("Origin"); origin != "" {
    w.Header().Set("Access-Control-Allow-Origin", origin)
}

Where is the right place to enable CORS in go-restful? I would assume a filter ...

Request.ReadEntity does not cache the entity for rereading

if a filter needs to read the entity before the actual endpoint does, this will cause an error because you cant reread the entity. it would be much better if ReadEntity cached the buffer on the request so it could be retrieved at a later time.

Question: Use for Google App Engine

Hi emicklei,
your project is awesome thanks for this impressions.
I've one question: Is it possible to use your project with die google app engine framework ?

Greets,
Moddus

QUESTION: Serving a File instead of a JSON/XML response

Hi emicklei, really love your library!

Is there any way to serve a zip file in one of my web services instead of returning a JSON or XML response?

What I want is to be able to call:

http.ServeFile(response, request, path.Join(rootdir, filename))

But I don't know how to extract the http.ResponseWriter and http.Request from your restful.Request and restful.Response.

Thanks in advance.

Why the following unit test fails

func TestSelectRoutesSlash2(t *testing.T) {
    ws1 := new(WebService).Path("/")
    ws1.Route(ws1.GET("/{type}/{id}"))
    ws1.Route(ws1.GET("/network/{id}"))
    routes := RouterJSR311{}.selectRoutes(ws1, "/network/12")
    if routes[0].Path != "/network/{id}" {
        t.Error("first is", routes[0].Path)
    }
}

Populating Models Schema on swagger-ui

Hi, sorry i might post this question in the wrong section. but if i may ask. i wonder how to document a model schema, so that it will show up in swagger-ui?

Thanks

Header parameter

I have a few header parameters that I use and I can get the underlying request to find it but it would be very nice to have it a first class parameter in the same way as body and path parameters.

If you are busy I don't mind contributing a patch if you are willing to accept pull requests and of course if you like the feature. ;)

Question about filters

I have implemented Filter (see below) and added it to the Container and I'm seeing an unexpected result.

In my log I see the following:
2013/10/05 21:45:22 Pre Filter
2013/10/05 21:45:22 Post Filter
2013/10/05 21:45:22 Returning from MyHandler

When I would have expected to see:
2013/10/05 21:45:22 Pre Filter
2013/10/05 21:45:22 Returning from MyHandler
2013/10/05 21:45:22 Post Filter

If I instead add the Filter to a Webservice my expected result. (Similar to the measureTime example).

I was thinking of Filters similar to Django middleware (They are executed like a stack) but it does not seem to be the case.

Is it possible to implement a Container filter that wraps a request. It would be nice to only have to add logging and instrumentation filters once to the container. Why do Container and Webservice filter behave differently?

Thanks for you time!

func PerformanceFilter(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
   log.Println("Pre Filter")
   chain.ProcessFilter(req, resp)
   log.Println("Post Filter")
}

BTW: Love the swagger support!

Multiple set header calls warnings

I get warnings from the standard library I guess about multiple calls to WriteHeader

2013/07/10 14:03:05 http: multiple response.WriteHeader calls

I think it is because go-restful detects mismatching content types and emits status code 406 (or some other in other cases) but still invokes the service method.

Isn't the idea to abort the call chain in case of an error?

Recover

currenty, the container has a catch all to recover panic situations and return 500 responses.
https://groups.google.com/forum/m/?fromgroups#!topic/golang-nuts/UvUcRAK4rsc triggered me to revise this. Additionally, experiments show a performance penalty for using the recover language feature. I intend to make this behavior configurable (DoNotRecover?) or just remove the construction and let users of the package decide how to handle panics in their Route functions.

Can't build the code

I'm trying to test out your framework for use with a Go based Google App Engine app but can't get past step 1. When I issue a command

go get github.com/emicklei/go-restful

It pulls it in and spews out several errors:

github.com/emicklei/go-restful

src/github.com/emicklei/go-restful/container.go:67: method c.dispatch is not an expression, must be called
src/github.com/emicklei/go-restful/container.go:79: method c.dispatch is not an expression, must be called
src/github.com/emicklei/go-restful/container.go:81: method c.dispatch is not an expression, must be called
src/github.com/emicklei/go-restful/curly.go:49: undefined: sort.Reverse
src/github.com/emicklei/go-restful/jsr311.go:109: undefined: sort.Reverse
src/github.com/emicklei/go-restful/jsr311.go:136: undefined: sort.Reverse
src/github.com/emicklei/go-restful/options_filter.go:21: method DefaultContainer.OPTIONSFilter is not an expression, must be called
src/github.com/emicklei/go-restful/request.go:48: r.Request.PostFormValue undefined (type *http.Request has no field or method PostFormValue)

Am I doing it wrong? I'm pretty new to Go and this is the first package outside the standard ones I am trying to use...

I'd like to kick off using this for a large project I am planning, so appreciate any assistance you can provide.

p.s. I found the fork by Moddus - but it does exactly the same thing.

Partial swagger functionality

I would like to avoid having swagger registering file server path to serv swagger-ui.
This is to support machine consumption of the swagger def but not having the actual swagger-ui. If I need it I can later stuff it in nginx or something infront of the services.

Return multiple JSON objects

Hi,
How can i return multiple JSON objects in one response?

type Organisation struct {
Channels    []ChannelEntry `bson:"channels"`
}

 type ChannelEntry struct {
 ChannelId bson.ObjectId `bson:"channel_id`
}

I fetch the attributes of the channel with its ID and then put them in another struct. However, I want to return all of the channels to the client in one response. How do i do this?

Feature: API Versioning

It would be really nice to implement API versioning. Not sure what the design would be, but this is a feature I think would be extremely beneficial to this project.

Filters to modify request?

Please excuse me opening a GH issue for what I think is really just a question.

I have a use case where each request relies on having it's own *sql.Tx, and when the request does not err out, that should be COMMITted, when the request errs it should be ROLLBACKed.

I had hoped to use filters for this - (as well as authentication), in both cases, I'd need to be able to arbitrarily inject something into the request context.

I couldn't see it documented, if I wouldn't be experimenting with go-restfully, I'd probably use http://www.gorillatoolkit.org/pkg/context

Thanks for a really cool package.

CORS Filter: Access-Control-Request-Headers more than one header will cause preflight to fail

Access-Control-Request-Headers can be a comma delimited list. when more than one element is in this list, isValidAccessControlRequestHeader in cors_filter.go will fail for even valid requests.

to test:

change cors_filter_test.go:20 to:
AllowedHeaders: []string{"X-Custom-Header, X-Additional-Header"},
and line 29 to:
httpRequest.Header.Set(HEADER_AccessControlRequestHeaders, "X-Custom-Header, X-Additional-Header")

Failure on consuming "text/plain": [restful] Unable to unmarshal content of type

Hi again,

Sorry to bother you in your sweet holidays :) .

Yesterday, I tried to consume a JSON data with cURL:

curl -v -H "Content-Type: application/json" -d '{"Name":"US"}' http://localhost:8080/user/4

It returns:

* About to connect() to localhost port 8080 (#0)
*   Trying 127.0.0.1... connected
> POST /user/4 HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: localhost:8080
> Accept: */*
> Content-Type: application/json
> Content-Length: 13
> 
* upload completely sent off: 13out of 13 bytes
< HTTP/1.1 201 Created
< Content-Type: text/plain; charset=utf-8
< Content-Length: 16
< Date: Tue, 23 Jul 2013 08:53:33 GMT
< 
{
  "Id": "4"
* Connection #0 to host localhost left intact
* Closing connection #0
 }

But today, I tried to consume "text/plain", and I change the code:

ws.Path("/user").Consumes(restful.MIME_JSON).Produces(restful.MIME_JSON)

to:

ws.Path("/user").Consumes("text/plain").Produces(restful.MIME_JSON)

and try

curl -v -H "Content-Type:text/plain" -d "Name=US" http://localhost:8080/user/4
* About to connect() to localhost port 8080 (#0)
*   Trying 127.0.0.1... connected
> POST /user/4 HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: localhost:8080
> Accept: */*
> Content-Type:text/plain
> Content-Length: 7
> 
* upload completely sent off: 7out of 7 bytes
< HTTP/1.1 500 Internal Server Error
< Content-Type: text/plain; charset=utf-8
< Content-Length: 56
< Date: Tue, 23 Jul 2013 09:01:34 GMT
< 
* Connection #0 to host localhost left intact
* Closing connection #0
[restful] Unable to unmarshal content of type:text/plain

The result is obviously not I want :( . I spent a whole day on this and it didn't work out, therefore I push an issue to you.

Hope you enjoy the rest of your holidays.

Regards,
Leo

restful-serve-static generates 406 on IE 9

I've been playing around with the examples and run into a snag with the restful-serve-static.go example on IE9. When running the example on FireFox/Chrome everything works as expected I receive the correct static content. However on IE9 I receive a 406: Not Acceptable.

The current Request being generated looks like the following:
Key Value
Request GET /static/FGH.html HTTP/1.1
Accept text/html, application/xhtml+xml, /
Accept-Language en-US
User-Agent Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
UA-CPU AMD64
Accept-Encoding gzip, deflate
Host localhost:8080
If-Modified-Since Wed, 16 Oct 2013 17:16:36 GMT
Connection Keep-Alive

Reading through the restul-options-filter example I see that we can identify the Consumes/Produces and I've tried setting up the Options. Can you point me in the right direction?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.