package for building REST-style Web Services using Go

go-restful

package for building REST-style Web Services using Google Go

Build Status 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

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

Without Go Modules

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

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

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 accesing 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, see go-restful-swagger12)
  • 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

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 jsoniter by build this package using a tag, e.g. go build -tags=jsoniter .

TODO: write examples of these.

Resources

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

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

Owner
Ernest Micklei
GCP Architect, Software Engineer, Google Developer Expert, Gopher, Dartian, Javanian, Smalltalker
Ernest Micklei
Comments
  • Go module support

    Go module support

    hi,

    i know that vgo is not released. but it would be great to support it in the near future. with the current version of vgo you cannot import a version-2 of go-restful. the design document says:

    Again, the go.mod file is required for v2 and later so that vgo can use the module line as a sign that the code has been written with semantic import versioning in mind, ...

    to support multiple versions, the packages should have the version in their import path (.../v2).

    so the author of vgo want the version 2 (or later versions) to have a go.mod file. this is not present in the current code. this leads to the following situation:

    $ vgo list -t github.com/emicklei/go-restful   
    github.com/emicklei/go-restful
            v1.0.0
            v1.0.1
            v1.1.0
            v1.1.1
            v1.1.2
            v1.1.3
    

    Great!

    $ vgo list -t github.com/emicklei/go-restful/v2
    github.com/emicklei/go-restful/v2
            v2.2.1
            v2.3.0
            v2.4.0
            v2.5.0
            v2.6.0
            v2.6.1
            v2.7.0
    

    Great!

    But:

    $ vgo get github.com/emicklei/go-restful/v2       
    vgo: finding github.com/emicklei/go-restful/v2 v2.7.0
    vgo: github.com/emicklei/go-restful/v2 v2.7.0: missing go.mod
    vgo: finding github.com/emicklei/go-restful/v2 v2.7.0
    vgo: github.com/emicklei/go-restful/v2 v2.7.0: missing go.mod
    vgo get: missing go.mod
    

    :-( Here vgo complains about the missing go.mod file which indicates that the module does semantic versioning.

    So adding a dependency with vgo:

    $ vgo get github.com/emicklei/[email protected] 
    $ vgo list -m
    github.com/cznic/fileutil             v0.0.0-20180108211300-6a051e75936f
    github.com/emicklei/go-restful        v0.0.0-20180416204930-2810ccc68e0c
    github.com/go-stack/stack             v1.7.0
    ...
    

    as you can see, go-restful is added as an unversioned dependency (0.0.0) with the current git-SHA (2810ccc68e0c). well, this works, but is is not the desired behaviour (at least for me).

    It would be great to support vgo in the long run. at the moment i have no problem with the 0.0.0 dependency but it would be great to support vgo in some later versions.

  • restful v2

    restful v2

    The idea is to start a new repository (but keeping the package name) that will introduce a new, improved, API to create REST-like applications in Go. With respect to the current status, this will be a major change (hence the v2) as I expect to see a few changes to the current API.

    This issue will list the things I like to change/improve

    • move Swagger to its own repository allowing for a 2.0 OpenAPI support
    • RouteFunction will have a Context parameter (as the last?)
    • Replace public vars by functions
    • Use CurlyRouter by default
    • No caching of request content by default
    • Introduce a static container in addition to the current one that allows add/remove WebServices
    • Remove request attributes in favor of Context

    Other suggestions are welcome.

  • Nested structs not returned in swagger output

    Nested structs not returned in swagger output

    I have a common response object that is returned on all my rest methods. Depending on the resource different parts of it is filled out. This use case doesnt work very well with swagger, only the container object is returned in the swagger model list and not the sub-structs.

    Here is an example: https://gist.github.com/viblo/7409083

  • How to detect if a connection is still pending

    How to detect if a connection is still pending

    Hi,

    I have a route handler that is asking as a long pool end. Basically I wait for a new message to come in on a channel and when that happens, I send this message as part of the response to the http request originated on a page using ajax.

    This works pretty well, but now I need a way to detect if the the browser is still waiting for the response, or if the browser moved on to another page.

    What happens now is that go-restful tries to send the response, but as there is no http connection listening, I kind of lose the message.

    If there is a way to detect that there is no more an http connection, I could simply resend the message to the channel I use, so that the next request will get it.

    (I hope it makes sense, I can post the code I have so far if that will help you)

    Thanks

    Diego

  • [security] Path parser inconsistency could lead to bypass several security checks in emicklei/go-restful

    [security] Path parser inconsistency could lead to bypass several security checks in emicklei/go-restful

    Reported via huntr.dev here.

    Created: May 28th 2022

    Description

    There is a inconsistency between how golang(and other packages) and go-restful parses url path. This incosistency could lead several security check bypass in a complex system.

    Steps to reproduce

    Copy and run the code below

    package main
    
    import (
        "fmt"
        "html"
        "log"
        "net/http"
    )
    
    func main() {
    
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
        })
    
    // If a user request matches with this path then it will be checked and if it didn't match then the request will be directly forwarded to the go-restful server.
        http.HandleFunc("/users/id_will_be_here", func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintf(w, "I'm checking if the user is authorized to see this user info. If he is authorized then I will forward this request to the go-restful server which will return the user info")
        })
    
        log.Fatal(http.ListenAndServe(":8081", nil))
    
    }
    

    Now If you send a request to the http://localhost:8081/users/id_will_be_here then you will get a hit to the expected endpoint and it will check the authorization part Now if you send a request to the http://localhost:8081/users/id_will_be_here/ (notice the extra / in last) then this server won't process this request as the path name doesn't match but the problem is that go-restful treat this path and the previous as same. So this inconsistency could lead some issues in this scenerio as the first sever wont check the security checks but the second server(go-restful) will return user data.

    Impact

    Security check bypass

    Occurrences

    web_service.go L80

  • Can't build the code

    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.

  • Produces(restful.MIME_JSON) Not Returning

    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
    }
    
  • Proposed addition of 'type' tag for swagger

    Proposed addition of 'type' tag for swagger

    Currently I have some struct fields that are essentially a type alias for an integer. They do not show up in my swagger documentation when I pass them to Reads(), they are omitted entirely. In the long term, it might be nice for the reflection magic in the swagger model_builder etc could detect these and handle them as though they were the appropriate type. Implementing a MarshalJSON method on my aliased type did get them to show up in the swagger documentation, but always as type "string" versus integer. This PR is much less ambitious than a fix for the above, but could prove generically useful in the event that we ever wanted to override the type that was guessed.

  • New method like `Response.WriteHeader` (respects content types in `Produces`)

    New method like `Response.WriteHeader` (respects content types in `Produces`)

    Method WriteHeader doesn't check Produces defined in Route / Path. Before 14 Sep headers was set in WriteEntity, because WriteHeader just set status code.

  • FilterChain should pass the request and response from filters to Target function

    FilterChain should pass the request and response from filters to Target function

    The PR #478 brought some weird changes that breaks the filters behaviour. We have a filter that creates another instance of Response to intercept all headers and data, then does an audit and modifies the data and only then it forwards to the original response. But the lambda added in that PR breaks this logic, since the target function writes directly to the original response.

  • Documentation: HTTP status codes

    Documentation: HTTP status codes

    Is there a way to have HTTP status codes in the (swagger) documentation? I figured there's ResponseMessages but not sure how to use since I haven't found anything in web_service.go

    I'd like to document the possible HTTP status codes, like 200, 201, 405 etc

    thanks

  • Tokenizer change in 3.10 breaks many URLs

    Tokenizer change in 3.10 breaks many URLs

    I'm using https://github.com/emicklei/go-restful/tree/67c9f7e97871832a5773f8a7c66230c7e3322e20/examples/openapi as the test case.

    This has the following content in go.mod:

    module github.com/emicklei/go-restful/examples/openapi
    
    go 1.14
    
    require (
            github.com/emicklei/go-restful-openapi/v2 v2.8.0
            github.com/emicklei/go-restful/v3 v3.8.0
            github.com/go-openapi/spec v0.20.4
    )
    

    Running this:

    ❯ go install
    
    ❯ go run ./restful-openapi.go
    2022/11/13 21:18:05 Get the API using http://localhost:8080/apidocs.json
    2022/11/13 21:18:05 Open Swagger UI using http://localhost:8080/apidocs/?url=http://localhost:8080/apidocs.json
    

    And in a second window:

    ❯ curl --silent -D - http://localhost:8080/apidocs.json | head -10
    HTTP/1.1 200 OK
    Content-Type: application/json
    Date: Sun, 13 Nov 2022 20:20:57 GMT
    Transfer-Encoding: chunked
    
    {
     "swagger": "2.0",
     "info": {
      "description": "Resource for managing Users",
      "title": "UserService",
    

    Upgraded to github.com/emicklei/go-restful/v3 v3.9.0:

    ❯ go get github.com/emicklei/go-restful/[email protected]
    go: upgraded github.com/emicklei/go-restful/v3 v3.8.0 => v3.9.0
    
    ❯ go run ./restful-openapi.go
    2022/11/13 21:21:25 Get the API using http://localhost:8080/apidocs.json
    2022/11/13 21:21:25 Open Swagger UI using http://localhost:8080/apidocs/?url=http://localhost:8080/apidocs.json
    

    Still good:

    ❯ curl --silent -D - http://localhost:8080/apidocs.json | head -10
    HTTP/1.1 200 OK
    Content-Type: application/json
    Date: Sun, 13 Nov 2022 20:21:48 GMT
    Transfer-Encoding: chunked
    
    {
     "swagger": "2.0",
     "info": {
      "description": "Resource for managing Users",
      "title": "UserService",
    

    But with 3.10:

    ❯ go get github.com/emicklei/go-restful/[email protected]
    go: upgraded github.com/emicklei/go-restful/v3 v3.9.0 => v3.10.0
    
    ❯ go run ./restful-openapi.go
    2022/11/13 21:22:09 Get the API using http://localhost:8080/apidocs.json
    2022/11/13 21:22:09 Open Swagger UI using http://localhost:8080/apidocs/?url=http://localhost:8080/apidocs.json
    

    It fails:

    ❯ curl --silent -D - http://localhost:8080/apidocs.json | head -10
    HTTP/1.1 404 Not Found
    Date: Sun, 13 Nov 2022 20:22:20 GMT
    Content-Length: 19
    Content-Type: text/plain; charset=utf-8
    
    404: Page Not Found
    

    Instead it suddenly requires a trailing slash:

    ❯ curl --silent -D - http://localhost:8080/apidocs.json/ | head -10
    HTTP/1.1 200 OK
    Content-Type: application/json
    Date: Sun, 13 Nov 2022 20:22:50 GMT
    Transfer-Encoding: chunked
    
    {
     "swagger": "2.0",
     "info": {
      "description": "Resource for managing Users",
      "title": "UserService",
    

    This is a breaking change that I did not expect in a stable release… And besides, the URL became ugly :)

lightweight, idiomatic and composable router for building Go HTTP services

chi is a lightweight, idiomatic and composable router for building Go HTTP services. It's especially good at helping you write large REST API services

Jan 6, 2023
A REST framework for quickly writing resource based services in Golang.

What is Resoursea? A high productivity web framework for quickly writing resource based services fully implementing the REST architectural style. This

Sep 27, 2022
A REST web-service sample project written in Golang using go-fiber, GORM and PostgreSQL

backend A REST web-service sample project written in Golang using go-fiber, GORM and PostgreSQL How to run Make sure you have Go installed (download).

Jan 1, 2023
Couper is a lightweight API gateway designed to support developers in building and operating API-driven Web projects
Couper is a lightweight API gateway designed to support developers in building and operating API-driven Web projects

Couper Couper is a lightweight API gateway designed to support developers in building and operating API-driven Web projects. Getting started The quick

Nov 18, 2022
REST Layer, Go (golang) REST API framework
REST Layer, Go (golang) REST API framework

REST Layer REST APIs made easy. REST Layer is an API framework heavily inspired by the excellent Python Eve. It helps you create a comprehensive, cust

Dec 16, 2022
REST api using fiber framework written in golang and using firebase ecosystem to authentication, storage and firestore as a db and use clean architecture as base
REST api using fiber framework written in golang and using firebase ecosystem to authentication, storage and firestore as a db and use clean architecture as base

Backend API Example FiberGo Framework Docs : https://github.com/gofiber Info This application using firebase ecosystem Firebase Auth Cloud Storage Fir

May 31, 2022
Vektor - Build production-grade web services quickly
Vektor - Build production-grade web services quickly

Vektor enables development of modern web services in Go. Vektor is designed to simplify the development of web APIs by eliminating boilerplate, using secure defaults, providing plug-in points, and offering common pieces needed for web apps. Vektor is fairly opinionated, but aims to provide flexibility in the right places.

Dec 15, 2022
A web app built using Go Buffalo web framework

Welcome to Buffalo Thank you for choosing Buffalo for your web development needs. Database Setup It looks like you chose to set up your application us

Feb 7, 2022
A very simple and powerful package for making REST requests with very little effort

Welcome to KRest KRest stands for Keep it simple REST Package. It's a very simple and powerful package wrapper over the standard http package for maki

Dec 1, 2022
Go WhatsApp REST API Implementation Using Fiber And Swagger
Go WhatsApp REST API Implementation Using Fiber And Swagger

Go WhatsApp REST API Implementation Using Fiber And Swagger Package cooljar/go-whatsapp-fiber Implements the WhatsApp Web API using Fiber web framewor

May 9, 2022
A Simple REST API Build Using Golang

gorestapi A Simple REST API Build Using Golang About gorestapi: a simple music restapi that retrives info about the author, album name, price of it ge

Nov 21, 2021
An example implementation of a REST interface in Golang using primarily the standard library.

REST API in Golang This is an example REST API implementation using primarily the standard library. The exceptions are as follows. github.com/gorilla/

Jan 22, 2022
REST API made using native Golang libraries. This API resembles the basic working of Instagram.
REST API made using native Golang libraries. This API resembles the basic working of Instagram.

Golang RESTful API for Instagram A Go based REST API built using native libraries. The API has been thoroughly worked through with Postman. Routes inc

Mar 16, 2022
Example Golang API backend rest implementation mini project Point Of Sale using Gin Framework and Gorm ORM Database.

Example Golang API backend rest implementation mini project Point Of Sale using Gin Framework and Gorm ORM Database.

Dec 23, 2022
Simple REST-API implementation using Golang with several packages (Echo, GORM) and Docker

Simple REST-API Boilerplate This is a simple implementation of REST-API using Golang and several packages (Echo and GORM). By default, I use PostgreSQ

Sep 13, 2022
🐶 Next generation building tool for nothing
🐶 Next generation building tool for nothing

Oscar ?? Next generation building tool for nothing Motivation Imitation is the sincerest form of flattery. Oscar is yet another nonsense activity gene

Nov 24, 2022
Building basic API with go, gin and gorm

Project Description Terima kasih sudah berkunjung ke halaman repositori ini, repositori ini berisi basic RESTFUL API dengan menggunakan teknologi seba

Nov 20, 2021
Flamingo Framework and Core Library. Flamingo is a go based framework for pluggable web projects. It is used to build scalable and maintainable (web)applications.
Flamingo Framework and Core Library. Flamingo is a go based framework for pluggable web projects. It is used to build scalable and maintainable (web)applications.

Flamingo Framework Flamingo is a web framework based on Go. It is designed to build pluggable and maintainable web projects. It is production ready, f

Jan 5, 2023
⚡ Rux is an simple and fast web framework. support middleware, compatible http.Handler interface. 简单且快速的 Go web 框架,支持中间件,兼容 http.Handler 接口

Rux Simple and fast web framework for build golang HTTP applications. NOTICE: v1.3.x is not fully compatible with v1.2.x version Fast route match, sup

Dec 8, 2022