new exporter version
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gosimple/slug"
|
||||
"github.com/xNok/go-rest-demo/pkg/recipes"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// create the Store and Recipe Handler
|
||||
store := recipes.NewMemStore()
|
||||
recipesHandler := NewRecipesHandler(store)
|
||||
home := homeHandler{}
|
||||
|
||||
router := mux.NewRouter()
|
||||
|
||||
router.HandleFunc("/", home.ServeHTTP)
|
||||
router.HandleFunc("/recipes", recipesHandler.ListRecipes).Methods("GET")
|
||||
router.HandleFunc("/recipes", recipesHandler.CreateRecipe).Methods("POST")
|
||||
router.HandleFunc("/recipes/{id}", recipesHandler.GetRecipe).Methods("GET")
|
||||
router.HandleFunc("/recipes/{id}", recipesHandler.UpdateRecipe).Methods("PUT")
|
||||
router.HandleFunc("/recipes/{id}", recipesHandler.DeleteRecipe).Methods("DELETE")
|
||||
|
||||
http.ListenAndServe(":8010", router)
|
||||
}
|
||||
|
||||
func InternalServerErrorHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte("500 Internal Server Error"))
|
||||
}
|
||||
|
||||
func NotFoundHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("404 Not Found"))
|
||||
}
|
||||
|
||||
type RecipesHandler struct {
|
||||
store recipeStore
|
||||
}
|
||||
|
||||
func NewRecipesHandler(s recipeStore) *RecipesHandler {
|
||||
return &RecipesHandler{
|
||||
store: s,
|
||||
}
|
||||
}
|
||||
|
||||
type recipeStore interface {
|
||||
Add(name string, recipe recipes.Recipe) error
|
||||
Get(name string) (recipes.Recipe, error)
|
||||
List() (map[string]recipes.Recipe, error)
|
||||
Update(name string, recipe recipes.Recipe) error
|
||||
Remove(name string) error
|
||||
}
|
||||
|
||||
func (h *RecipesHandler) CreateRecipe(w http.ResponseWriter, r *http.Request) {
|
||||
// Recipe object that will be populated from json payload
|
||||
var recipe recipes.Recipe
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&recipe); err != nil {
|
||||
InternalServerErrorHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
resourceID := slug.Make(recipe.Name)
|
||||
|
||||
if err := h.store.Add(resourceID, recipe); err != nil {
|
||||
InternalServerErrorHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func (h *RecipesHandler) ListRecipes(w http.ResponseWriter, r *http.Request) {
|
||||
recipes, err := h.store.List()
|
||||
|
||||
jsonBytes, err := json.Marshal(recipes)
|
||||
if err != nil {
|
||||
InternalServerErrorHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(jsonBytes)
|
||||
}
|
||||
|
||||
func (h *RecipesHandler) GetRecipe(w http.ResponseWriter, r *http.Request) {
|
||||
id := mux.Vars(r)["id"]
|
||||
|
||||
recipe, err := h.store.Get(id)
|
||||
if err != nil {
|
||||
if err == recipes.NotFoundErr {
|
||||
NotFoundHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
InternalServerErrorHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
jsonBytes, err := json.Marshal(recipe)
|
||||
if err != nil {
|
||||
InternalServerErrorHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(jsonBytes)
|
||||
}
|
||||
|
||||
func (h *RecipesHandler) UpdateRecipe(w http.ResponseWriter, r *http.Request) {
|
||||
id := mux.Vars(r)["id"]
|
||||
|
||||
// Recipe object that will be populated from json payload
|
||||
var recipe recipes.Recipe
|
||||
if err := json.NewDecoder(r.Body).Decode(&recipe); err != nil {
|
||||
InternalServerErrorHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.store.Update(id, recipe); err != nil {
|
||||
if err == recipes.NotFoundErr {
|
||||
NotFoundHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
InternalServerErrorHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
jsonBytes, err := json.Marshal(recipe)
|
||||
if err != nil {
|
||||
InternalServerErrorHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(jsonBytes)
|
||||
}
|
||||
|
||||
func (h *RecipesHandler) DeleteRecipe(w http.ResponseWriter, r *http.Request) {
|
||||
id := mux.Vars(r)["id"]
|
||||
|
||||
if err := h.store.Remove(id); err != nil {
|
||||
InternalServerErrorHandler(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
type homeHandler struct{}
|
||||
|
||||
func (h *homeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("This is my home page"))
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
###
|
||||
POST http://localhost:8010/recipes
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "Ham and cheese toasties",
|
||||
"ingredients": [
|
||||
{
|
||||
"name": "bread"
|
||||
},{
|
||||
"name": "ham"
|
||||
},{
|
||||
"name": "cheese"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
> {%
|
||||
client.test("Request executed successfully", function() {
|
||||
client.assert(response.status === 200, "Response status is not 200");
|
||||
});
|
||||
%}
|
||||
|
||||
###
|
||||
GET http://localhost:8010/recipes
|
||||
|
||||
> {%
|
||||
client.test("Request executed successfully", function() {
|
||||
client.assert(response.status === 200, "Response status is not 200");
|
||||
client.assert(response.body === "{\"ham-and-cheese-toasties\":{\"name\":\"Ham and cheese toasties\",\"ingredients\":[{\"name\":\"bread\"},{\"name\":\"ham\"},{\"name\":\"cheese\"}]}}", "Body match expected response")
|
||||
});
|
||||
%}
|
||||
|
||||
###
|
||||
GET http://localhost:8010/recipes/ham-and-cheese-toasties
|
||||
|
||||
> {%
|
||||
client.test("Request executed successfully", function() {
|
||||
client.assert(response.status === 200, "Response status is not 200");
|
||||
client.assert(response.body === "{\"name\":\"Ham and cheese toasties\",\"ingredients\":[{\"name\":\"bread\"},{\"name\":\"ham\"},{\"name\":\"cheese\"}]}", "Body match expected response")
|
||||
});
|
||||
%}
|
||||
|
||||
###
|
||||
PUT http://localhost:8010/recipes/ham-and-cheese-toasties
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "Ham and cheese toasties",
|
||||
"ingredients": [
|
||||
{
|
||||
"name": "bread"
|
||||
},{
|
||||
"name": "ham"
|
||||
},{
|
||||
"name": "cheese"
|
||||
},{
|
||||
"name": "butter"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
> {%
|
||||
client.test("Request executed successfully", function() {
|
||||
client.assert(response.status === 200, "Response status is not 200");
|
||||
});
|
||||
%}
|
||||
|
||||
###
|
||||
GET http://localhost:8010/recipes/ham-and-cheese-toasties
|
||||
|
||||
> {%
|
||||
client.test("Request executed successfully", function() {
|
||||
client.assert(response.status === 200, "Response status is not 200");
|
||||
client.assert(response.body === "{\"name\":\"Ham and cheese toasties\",\"ingredients\":[{\"name\":\"bread\"},{\"name\":\"ham\"},{\"name\":\"cheese\"},{\"name\":\"butter\"}]}", "Body match expected response")
|
||||
|
||||
});
|
||||
%}
|
||||
|
||||
###
|
||||
DELETE http://localhost:8010/recipes/ham-and-cheese-toasties
|
||||
|
||||
> {%
|
||||
client.test("Request executed successfully", function() {
|
||||
client.assert(response.status === 200, "Response status is not 200");
|
||||
});
|
||||
%}
|
||||
|
||||
###
|
||||
GET http://localhost:8010/recipes/ham-and-cheese-toasties
|
||||
|
||||
> {%
|
||||
client.test("Request executed successfully", function() {
|
||||
client.assert(response.status === 404, "Response status is not 404");
|
||||
});
|
||||
%}
|
||||
Reference in New Issue
Block a user