Created
October 1, 2014 16:43
-
-
Save hourback/c2672cbc05d80c2e279a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"net/http" | |
"strconv" | |
"os" | |
"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 (NotificationResource) 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 | |
// <User><Id>1</Id><Name>Melissa Raspberry</Name></User> | |
// | |
// GET http://localhost:8080/users/1 | |
// | |
// PUT http://localhost:8080/users/1 | |
// <User><Id>1</Id><Name>Melissa</Name></User> | |
// | |
// DELETE http://localhost:8080/users/1 | |
// | |
type Notification struct { | |
Id, Status, DescriptionOfProblem string | |
} | |
type NotificationResource struct { | |
// normally one would use DAO (data access object) | |
notifications map[string]Notification | |
} | |
func (u NotificationResource) Register(container *restful.Container) { | |
ws := new(restful.WebService) | |
ws. | |
Path("/notifications"). | |
Doc("Manage Notifications"). | |
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("/").To(u.findAllNotifications). | |
// docs | |
Doc("get all notifications"). | |
Operation("findAllNotifications"). | |
Writes(Notification{})) // on the response | |
ws.Route(ws.GET("/{notification-id}").To(u.findNotification). | |
// docs | |
Doc("get a notification"). | |
Operation("findNotification"). | |
Param(ws.PathParameter("notification-id", "identifier of the notification").DataType("string")). | |
Writes(Notification{})) // on the response | |
ws.Route(ws.PUT("/{notification-id}").To(u.updateNotification). | |
// docs | |
Doc("update a notification"). | |
Operation("updateNotification"). | |
Param(ws.PathParameter("notification-id", "identifier of the notification").DataType("string")). | |
Reads(Notification{})) // from the request | |
ws.Route(ws.POST("").To(u.createNotification). | |
// docs | |
Doc("create a notification"). | |
Operation("createNotification"). | |
Reads(Notification{})) // from the request | |
ws.Route(ws.DELETE("/{notification-id}").To(u.removeNotification). | |
// docs | |
Doc("delete a notification"). | |
Operation("removeNotification"). | |
Param(ws.PathParameter("notification-id", "identifier of the notification").DataType("string"))) | |
container.Add(ws) | |
} | |
// GET http://localhost:8080/notifications/ | |
// | |
func (u NotificationResource) findAllNotifications(request *restful.Request, response *restful.Response) { | |
fmt.Println("Entering handler....") | |
fmt.Println(u) | |
all := []Notification{} | |
for key, _ := range u.notifications { | |
usr := u.notifications[key] | |
//fmt.Println("Id:", Id, "Status:", Status, "DescriptionOfProblem:", DescriptionOfProblem) | |
fmt.Println(usr) | |
all = append(all, usr) | |
//response.WriteEntity(usr) | |
} | |
fmt.Println(all) | |
response.WriteEntity(all) | |
fmt.Println("Exiting handler....") | |
} | |
// GET http://localhost:8080/users/1 | |
// | |
func (u NotificationResource) findNotification(request *restful.Request, response *restful.Response) { | |
id := request.PathParameter("notification-id") | |
usr := u.notifications[id] | |
if len(usr.Id) == 0 { | |
response.AddHeader("Content-Type", "text/plain") | |
response.WriteErrorString(http.StatusNotFound, "404: Notification could not be found.") | |
return | |
} | |
response.WriteEntity(usr) | |
} | |
// POST http://localhost:8080/users | |
// <User><Name>Melissa</Name></User> | |
// | |
func (u *NotificationResource) createNotification(request *restful.Request, response *restful.Response) { | |
usr := new(Notification) | |
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.notifications) + 1) // simple id generation | |
u.notifications[usr.Id] = *usr | |
response.WriteHeader(http.StatusCreated) | |
response.WriteEntity(usr) | |
} | |
// PUT http://localhost:8080/users/1 | |
// <User><Id>1</Id><Name>Melissa Raspberry</Name></User> | |
// | |
func (u *NotificationResource) updateNotification(request *restful.Request, response *restful.Response) { | |
usr := new(Notification) | |
err := request.ReadEntity(&usr) | |
if err != nil { | |
response.AddHeader("Content-Type", "text/plain") | |
response.WriteErrorString(http.StatusInternalServerError, err.Error()) | |
return | |
} | |
u.notifications[usr.Id] = *usr | |
response.WriteEntity(usr) | |
} | |
// DELETE http://localhost:8080/users/1 | |
// | |
func (u *NotificationResource) removeNotification(request *restful.Request, response *restful.Response) { | |
id := request.PathParameter("notification-id") | |
delete(u.notifications, 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 := NotificationResource{map[string]Notification{}} | |
u.Register(wsContainer) | |
u.notifications["1"] = Notification{Id: "1", Status: "OPEN", DescriptionOfProblem: "Network outage"} | |
u.notifications["2"] = Notification{Id: "2", Status: "CLOSED", DescriptionOfProblem: "Hardware failure"} | |
u.notifications["3"] = Notification{Id: "3", Status: "", DescriptionOfProblem: "Unknown"} | |
// Add container filter to enable CORS | |
cors := restful.CrossOriginResourceSharing{ | |
ExposeHeaders: []string{"Content-Length", "Origin"}, | |
AllowedHeaders: []string{"Content-Type", "Origin", "x-requested-with"}, | |
CookiesAllowed: false, | |
Container: wsContainer} | |
wsContainer.Filter(cors.Filter) | |
// Add container filter to respond to OPTIONS | |
wsContainer.Filter(wsContainer.OPTIONSFilter) | |
// 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://192.168.59.103:8080", | |
ApiPath: "/apidocs.json", | |
// Optionally, specifiy where the UI is located | |
SwaggerPath: "/apidocs/", | |
SwaggerFilePath: "/data/swagger-ui-master/swagger-ui-master/dist"} | |
swagger.RegisterSwaggerService(config, wsContainer) | |
log.Printf("start listening on 192.168.59.103:8080") | |
server := &http.Server{Addr: ":8080", Handler: wsContainer} | |
log.Fatal(server.ListenAndServe()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm trying to return multiple JSON objects:
emicklei/go-restful#51