FAQ
Hi,

I know there are several other such packages available in the open-source.
I created this as part of my learning Go project and because I wanted to
explore other implementations to specify the api of a service. The code is
at https://github.com/emicklei/go-restful

I wrote about the iterations of this design on
http://ernestmicklei.com/2012/11/11/go-restful-api-design/ .

On http://ernestmicklei.com/2012/11/24/go-restful-first-working-example/you can read about a basic example using go-restful.

^ Ernest

--

Search Discussions

  • Kevin Gillette at Nov 27, 2012 at 4:42 am
    Though I've not traced through the entire API, the current implementation
    restful.Dispatch seems like it will very easily do the unexpected thing --
    it tries every registered handler (most of which would presumably return
    http.StatusNotFound or http.MethodNotAllowed if the path or method
    mismatched), rather than using a map to dispatch only to the handlers that
    should be allowed to handle that particular request. Doing so would likely
    require a notion of a path prefix for each service, though that notion
    already seems to be in place anyway.

    The reason I say it will do the unexpected thing, is that the convention
    for how http is handled in go, is that handlers are given precedence by
    specificity, rather than the order of registration, and when the handler is
    invoked, whatever response code it returns will be delivered to the client.
    Dispatch will keep trying service handlers until one returns exactly
    http.StatusOK. It's very common for REST services to return
    http.StatusCreated or http.StatusNoContent from POST requests, or 3xx and
    4xx codes that should be treated as final and authoritative. Based on the
    current implementation, if a non http.StatusOK code is returned, further
    handlers will be tried, even if output was written to the client -- any
    number of these other handlers could send extra output to the client, such
    jpeg data, without knowing that plaintext log data had been sent by another
    handler in the same request.

    A quick fix could be to use a special, negative, status code when a handler
    did not attempt to handle the request, and try handlers until any
    non-negative code has been returned to the main dispatcher. At least this
    way, while the handling priority would still follow registration order, it
    would at least prevent multiple services from uncooperatively handling the
    same request.

    --
  • Ernest Micklei at Nov 27, 2012 at 8:24 am
    @Kevin

    Thank you for your time looking at this package.

    Reading through your comments, I agree about the dispatch flow leading to
    potential problems. I will try a different design, most likely using a map
    as you suggested.
    On Tuesday, November 27, 2012 5:42:15 AM UTC+1, Kevin Gillette wrote:

    Though I've not traced through the entire API, the current implementation
    restful.Dispatch seems like it will very easily do the unexpected thing --
    it tries every registered handler (most of which would presumably return
    http.StatusNotFound or http.MethodNotAllowed if the path or method
    mismatched), rather than using a map to dispatch only to the handlers that
    should be allowed to handle that particular request. Doing so would likely
    require a notion of a path prefix for each service, though that notion
    already seems to be in place anyway.

    The reason I say it will do the unexpected thing, is that the convention
    for how http is handled in go, is that handlers are given precedence by
    specificity, rather than the order of registration, and when the handler is
    invoked, whatever response code it returns will be delivered to the client.
    Dispatch will keep trying service handlers until one returns exactly
    http.StatusOK. It's very common for REST services to return
    http.StatusCreated or http.StatusNoContent from POST requests, or 3xx and
    4xx codes that should be treated as final and authoritative. Based on the
    current implementation, if a non http.StatusOK code is returned, further
    handlers will be tried, even if output was written to the client -- any
    number of these other handlers could send extra output to the client, such
    jpeg data, without knowing that plaintext log data had been sent by another
    handler in the same request.

    A quick fix could be to use a special, negative, status code when a
    handler did not attempt to handle the request, and try handlers until any
    non-negative code has been returned to the main dispatcher. At least this
    way, while the handling priority would still follow registration order, it
    would at least prevent multiple services from uncooperatively handling the
    same request.
    --
  • Ernest Micklei at Dec 18, 2012 at 2:40 pm
    (update)

    I have completely re-written and tested the dispatch flow and choose to
    build it conform the
    JSR311 http://jsr311.java.net/nonav/releases/1.1/spec/spec.html which
    describes in detail how an incoming Http request should be matched with
    available Webservices and their Routes (Method+Parameterized Path+Accept).
    Furthermore, I have extended the Route building API such that more detailed
    documentation can be produced (doc per operation, doc and type per
    parameter, etc.)

    ^ Ernest

    Op dinsdag 27 november 2012 09:24:11 UTC+1 schreef Ernest Micklei het
    volgende:
    @Kevin

    Thank you for your time looking at this package.

    Reading through your comments, I agree about the dispatch flow leading to
    potential problems. I will try a different design, most likely using a map
    as you suggested.
    On Tuesday, November 27, 2012 5:42:15 AM UTC+1, Kevin Gillette wrote:

    Though I've not traced through the entire API, the current implementation
    restful.Dispatch seems like it will very easily do the unexpected thing --
    it tries every registered handler (most of which would presumably return
    http.StatusNotFound or http.MethodNotAllowed if the path or method
    mismatched), rather than using a map to dispatch only to the handlers that
    should be allowed to handle that particular request. Doing so would likely
    require a notion of a path prefix for each service, though that notion
    already seems to be in place anyway.

    The reason I say it will do the unexpected thing, is that the convention
    for how http is handled in go, is that handlers are given precedence by
    specificity, rather than the order of registration, and when the handler is
    invoked, whatever response code it returns will be delivered to the client.
    Dispatch will keep trying service handlers until one returns exactly
    http.StatusOK. It's very common for REST services to return
    http.StatusCreated or http.StatusNoContent from POST requests, or 3xx and
    4xx codes that should be treated as final and authoritative. Based on the
    current implementation, if a non http.StatusOK code is returned, further
    handlers will be tried, even if output was written to the client -- any
    number of these other handlers could send extra output to the client, such
    jpeg data, without knowing that plaintext log data had been sent by another
    handler in the same request.

    A quick fix could be to use a special, negative, status code when a
    handler did not attempt to handle the request, and try handlers until any
    non-negative code has been returned to the main dispatcher. At least this
    way, while the handling priority would still follow registration order, it
    would at least prevent multiple services from uncooperatively handling the
    same request.
    --
  • Ernest Micklei at May 22, 2013 at 9:19 pm
    Hi,

    Just merged a new major feature to this package: Filters.

    A filter dynamically intercepts requests and responses to transform or use
    the information contained in the requests or responses.
    You can use filters to perform generic logging, measurement,
    authentication, redirect, set response headers etc.
    Each filter must define a FilterFunction:

          func (req *restful.Request, resp *restful.Response, chain
    *restful.FilterChain)

    Use the following statement to pass the request,response pair to the next
    filter or RouteFunction

          chain.ProcessFilter(req, resp)


    In the restful package there are three hooks into the request,response flow
    where filters can be added.

    - restful.Filter(...) globally for all registered WebServices
    - yourservice.Filter(...) for all routes of your WebService
    - routeBuilder.Filter(...) for this particular Route being build

    Filters can be chained together ; just call Filter(..) for each. Each
    filter can decide to abort or pass the request to the next.
    Typical examples of filters are: loggers, timers/counters, authentication,
    special headers set/get,...
    See the examples folder for such implementations.

    Be RESTful,

    - Ernest

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 26, '12 at 9:56p
activeMay 22, '13 at 9:19p
posts5
users2
websitegolang.org

2 users in discussion

Ernest Micklei: 4 posts Kevin Gillette: 1 post

People

Translate

site design / logo © 2022 Grokbase