package main import ( "log" "net/http" "strconv" "github.com/emicklei/go-restful" "github.com/emicklei/go-restful/swagger" ) // This example show a complete (GET,PUT,POST,DELETE) conventional example of // a REST Resource including documentation to be served by e.g. a Swagger UI // It is recommended to create a Resource struct (UserResource) that can encapsulate // an object that provide domain access (a DAO) // It has a Register method including the complete Route mapping to methods together // with all the appropriate documentation // // POST http://localhost:8080/users // 1Melissa Raspberry // // GET http://localhost:8080/users/1 // // PUT http://localhost:8080/users/1 // 1Melissa // // DELETE http://localhost:8080/users/1 // type User struct { Id, Name string } type UserResource struct { // normally one would use DAO (data access object) users map[string]User } func (u UserResource) Register(container *restful.Container) { ws := new(restful.WebService) ws. Path("/users"). Doc("Manage Users"). 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("/{user-id}").To(u.findUser). // docs Doc("get a user"). Operation("findUser"). Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")). Writes(User{})) // on the response ws.Route(ws.PUT("/{user-id}").To(u.updateUser). // docs Doc("update a user"). Operation("updateUser"). Param(ws.PathParameter("user-id", "identifier of the user").DataType("string")). ReturnsError(409, "duplicate user-id", nil). Reads(User{})) // from the request ws.Route(ws.POST("").To(u.createUser). // docs Doc("create a user"). Operation("createUser"). Reads(User{})) // from the request ws.Route(ws.DELETE("/{user-id}").To(u.removeUser). // docs Doc("delete a user"). Operation("removeUser"). Param(ws.PathParameter("user-id", "identifier of the user").DataType("string"))) container.Add(ws) } // GET http://localhost:8080/users/1 // func (u UserResource) findUser(request *restful.Request, response *restful.Response) { id := request.PathParameter("user-id") usr := u.users[id] if len(usr.Id) == 0 { response.AddHeader("Content-Type", "text/plain") response.WriteErrorString(http.StatusNotFound, "404: User could not be found.") return } response.WriteEntity(usr) } // POST http://localhost:8080/users // Melissa // func (u *UserResource) createUser(request *restful.Request, response *restful.Response) { usr := new(User) err := request.ReadEntity(usr) if err != nil { response.AddHeader("Content-Type", "text/plain") response.WriteErrorString(http.StatusInternalServerError, err.Error()) return } usr.Id = strconv.Itoa(len(u.users) + 1) // simple id generation u.users[usr.Id] = *usr response.WriteHeaderAndEntity(http.StatusCreated, usr) } // PUT http://localhost:8080/users/1 // 1Melissa Raspberry // func (u *UserResource) updateUser(request *restful.Request, response *restful.Response) { usr := new(User) err := request.ReadEntity(&usr) if err != nil { response.AddHeader("Content-Type", "text/plain") response.WriteErrorString(http.StatusInternalServerError, err.Error()) return } u.users[usr.Id] = *usr response.WriteEntity(usr) } // DELETE http://localhost:8080/users/1 // func (u *UserResource) removeUser(request *restful.Request, response *restful.Response) { id := request.PathParameter("user-id") delete(u.users, id) } func main() { // to see what happens in the package, uncomment the following //restful.TraceLogger(log.New(os.Stdout, "[restful] ", log.LstdFlags|log.Lshortfile)) wsContainer := restful.NewContainer() u := UserResource{map[string]User{}} u.Register(wsContainer) // 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: wsContainer.RegisteredWebServices(), // you control what services are visible WebServicesUrl: "http://localhost:8080", ApiPath: "/apidocs.json", // Optionally, specifiy where the UI is located SwaggerPath: "/apidocs/", SwaggerFilePath: "/Users/emicklei/xProjects/swagger-ui/dist"} swagger.RegisterSwaggerService(config, wsContainer) log.Printf("start listening on localhost:8080") server := &http.Server{Addr: ":8080", Handler: wsContainer} log.Fatal(server.ListenAndServe()) }