コード例 #1
0
ファイル: main.go プロジェクト: MarvinMenzerath/UpAndRunning2
// Setup all routes for API v2
func setupApi2(router *httprouter.Router) {
	router.GET("/api/v2", APIv2.ApiIndexVersion)

	// Public Statistics
	router.GET("/api/v2/websites", APIv2.ApiWebsites)
	router.GET("/api/v2/websites/:url/status", APIv2.ApiWebsitesStatus)
	router.GET("/api/v2/websites/:url/results", APIv2.ApiWebsitesResults)

	// Authentication
	router.POST("/api/v2/auth/login", APIv2.ApiAuthLogin)
	router.GET("/api/v2/auth/logout", APIv2.ApiAuthLogout)

	// Settings
	router.PUT("/api/v2/settings/password", APIv2.ApiSettingsPassword)
	router.PUT("/api/v2/settings/interval", APIv2.ApiSettingsInterval)

	// Website Management
	router.POST("/api/v2/websites/:url", APIv2.ApiWebsitesAdd)
	router.PUT("/api/v2/websites/:url", APIv2.ApiWebsitesEdit)
	router.DELETE("/api/v2/websites/:url", APIv2.ApiWebsitesDelete)
	router.PUT("/api/v2/websites/:url/enabled", APIv2.ApiWebsitesEnabled)
	router.PUT("/api/v2/websites/:url/visibility", APIv2.ApiWebsitesVisibility)
	router.GET("/api/v2/websites/:url/notifications", APIv2.ApiWebsitesGetNotifications)
	router.PUT("/api/v2/websites/:url/notifications", APIv2.ApiWebsitePutNotifications)
	router.GET("/api/v2/websites/:url/check", APIv2.ApiWebsiteCheck)
}
コード例 #2
0
ファイル: pubsub.go プロジェクト: pengux/pub-sub
// SetupRoutes maps routes to the PubSub's handlers
func (ps *PubSub) SetupRoutes(router *httprouter.Router) *httprouter.Router {
	router.POST("/:topic_name", ps.PublishMessage)
	router.POST("/:topic_name/:subscriber_name", ps.Subscribe)
	router.DELETE("/:topic_name/:subscriber_name", ps.Unsubscribe)
	router.GET("/:topic_name/:subscriber_name", ps.GetMessages)

	return router
}
コード例 #3
0
ファイル: stream_controller.go プロジェクト: ello/streams
func (c *streamController) Register(router *httprouter.Router) {
	router.PUT("/streams", basicAuth(timeRequest(c.handle(c.addToStream), addToStreamTimer), c.authConfig))
	router.DELETE("/streams", basicAuth(timeRequest(c.handle(c.removeFromStream), removeFromStreamTimer), c.authConfig))
	router.POST("/streams/coalesce", basicAuth(timeRequest(c.handle(c.coalesceStreams), coalesceTimer), c.authConfig))
	router.GET("/stream/:id", basicAuth(timeRequest(c.handle(c.getStream), getStreamTimer), c.authConfig))

	log.Debug("Routes Registered")
}
コード例 #4
0
ファイル: dump.go プロジェクト: janhalfar/dumpster
func (d *Dump) Register(r *httprouter.Router) {
	r.GET("/dump", d.GetDumps)
	r.GET("/dump/:type", d.GetDumpsForType)
	r.GET("/dump/:type/:id", d.Get)
	r.DELETE("/dump/:type/:id", d.Delete)
	r.POST("/dump/:type", d.Create)
	r.GET("/dumpremote", d.GetAllRemoteDumps)
	r.GET("/dumpremote/:name", d.GetRemoteDumps)
}
コード例 #5
0
ファイル: handlers_queue.go プロジェクト: teefax/tmail
// addQueueHandlers add Queue handlers to router
func addQueueHandlers(router *httprouter.Router) {
	// get all message in queue
	router.GET("/queue", wrapHandler(queueGetMessages))
	// get a message by id
	router.GET("/queue/:id", wrapHandler(queueGetMessage))
	// discard a message
	router.DELETE("/queue/discard/:id", wrapHandler(queueDiscardMessage))
	// bounce a message
	router.DELETE("/queue/bounce/:id", wrapHandler(queueBounceMessage))
}
コード例 #6
0
ファイル: rule_controller.go プロジェクト: robertocs/cepiot
func AddRoutes(router *httprouter.Router) {
	mylog.Debugf("enter rule.AddRoutes(%+v)", router)
	defer func() { mylog.Debugf("exit rule.AddRoutes(%+v)", router) }()

	controller := &controller{}
	router.GET("/rules", controller.GetAll)
	router.GET("/rules/:name", controller.Get)
	router.POST("/rules", controller.Post)
	router.DELETE("/rules/:name", controller.Del)
}
コード例 #7
0
func (h *Handler) SetRoutes(r *httprouter.Router) {
	r.POST("/keys/:set", h.Create)
	r.PUT("/keys/:set", h.UpdateKeySet)
	r.GET("/keys/:set", h.GetKeySet)
	r.DELETE("/keys/:set", h.DeleteKeySet)

	r.PUT("/keys/:set/:key", h.UpdateKey)
	r.GET("/keys/:set/:key", h.GetKey)
	r.DELETE("/keys/:set/:key", h.DeleteKey)

}
コード例 #8
0
ファイル: http.go プロジェクト: imjorge/flynn
func (api *HTTPAPI) RegisterRoutes(r *httprouter.Router) {
	r.POST("/storage/providers", api.CreateProvider)
	r.POST("/storage/providers/:provider_id/volumes", api.Create)
	r.GET("/storage/volumes", api.List)
	r.GET("/storage/volumes/:volume_id", api.Inspect)
	r.DELETE("/storage/volumes/:volume_id", api.Destroy)
	r.PUT("/storage/volumes/:volume_id/snapshot", api.Snapshot)
	// takes host and volID parameters, triggers a send on the remote host and give it a list of snaps already here, and pipes it into recv
	r.POST("/storage/volumes/:volume_id/pull_snapshot", api.Pull)
	// responds with a snapshot stream binary.  only works on snapshots, takes 'haves' parameters, usually called by a node that's servicing a 'pull_snapshot' request
	r.GET("/storage/volumes/:volume_id/send", api.Send)
}
コード例 #9
0
ファイル: handlers_users.go プロジェクト: ro78/tmail
// addUsersHandlers add Users handler to router
func addUsersHandlers(router *httprouter.Router) {
	// add user
	router.POST("/users/:user", wrapHandler(usersAdd))

	// get all users
	router.GET("/users", wrapHandler(usersGetAll))

	// get one user
	router.GET("/users/:user", wrapHandler(usersGetOne))

	// del an user
	router.DELETE("/users/:user", wrapHandler(usersDel))
}
コード例 #10
0
ファイル: routes.go プロジェクト: adventure-awaits/api
// RegisterRoutes initializes the routes for the service
func RegisterRoutes(r *httprouter.Router) {
	UC := controllers.NewUserController()
	AC := controllers.NewAdventureController()

	r.GET("/users/:id", UC.Get)
	r.POST("/users", UC.Create)
	r.DELETE("/users/:id", UC.Remove)

	r.GET("/adventures", AC.GetAll)
	r.GET("/adventures/:id", AC.Get)
	r.POST("/adventures", AC.Create)
	r.DELETE("/adventures/:id", AC.Remove)
}
コード例 #11
0
ファイル: http.go プロジェクト: ably-forks/flynn
func (h *jobAPI) RegisterRoutes(r *httprouter.Router) error {
	r.GET("/host/jobs", h.ListJobs)
	r.GET("/host/jobs/:id", h.GetJob)
	r.PUT("/host/jobs/:id", h.AddJob)
	r.DELETE("/host/jobs/:id", h.StopJob)
	r.PUT("/host/jobs/:id/signal/:signal", h.SignalJob)
	r.POST("/host/pull/images", h.PullImages)
	r.POST("/host/pull/binaries", h.PullBinariesAndConfig)
	r.POST("/host/discoverd", h.ConfigureDiscoverd)
	r.POST("/host/network", h.ConfigureNetworking)
	r.GET("/host/status", h.GetStatus)
	r.POST("/host/resource-check", h.ResourceCheck)
	r.POST("/host/update", h.Update)
	r.POST("/host/tags", h.UpdateTags)
	return nil
}
コード例 #12
0
ファイル: service_http.go プロジェクト: joyent/gomanta
// setupHTTP attaches all the needed handlers to provide the HTTP API.
func (m *Manta) SetupHTTP(mux *httprouter.Router) {

	baseRoute := "/" + m.ServiceInstance.UserAccount
	mux.NotFound = ErrNotFound
	mux.MethodNotAllowed = ErrNotAllowed
	mux.RedirectFixedPath = true
	mux.RedirectTrailingSlash = true
	mux.HandleMethodNotAllowed = true

	// this particular route can't be handled by httprouter correctly due to its
	// handling of positional parameters but we can't just pass in ErrNotAllowed
	// either because it's the wrong type
	handleNotAllowed := func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		w.WriteHeader(http.StatusMethodNotAllowed)
		w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
		w.Write([]byte("Method is not allowed"))
	}
	mux.POST(baseRoute+"/stor", handleNotAllowed)

	// storage APIs
	// PutSnapLink and PutMetaData have the same route spec as other routes
	// in this group, which isn't permitted by httprouter. We pick up the
	// correct path in the handler
	mux.PUT(baseRoute+"/stor/:dir", m.handler((*Manta).handleStorage))         // PutDirectory
	mux.GET(baseRoute+"/stor/:dir", m.handler((*Manta).handleStorage))         // ListDirectory
	mux.DELETE(baseRoute+"/stor/:dir", m.handler((*Manta).handleStorage))      // DeleteDirectory
	mux.PUT(baseRoute+"/stor/:dir/:obj", m.handler((*Manta).handleStorage))    // PutObject
	mux.GET(baseRoute+"/stor/:dir/:obj", m.handler((*Manta).handleStorage))    // GetObject
	mux.DELETE(baseRoute+"/stor/:dir/:obj", m.handler((*Manta).handleStorage)) // DeleteObject

	// job APIs
	mux.POST(baseRoute+"/jobs", m.handler((*Manta).handleJobs))                 // CreateJob
	mux.POST(baseRoute+"/jobs/:id/live/in", m.handler((*Manta).handleJobs))     // AddJobInputs
	mux.POST(baseRoute+"/jobs/:id/live/in/end", m.handler((*Manta).handleJobs)) // EndJobInput
	mux.POST(baseRoute+"/jobs/:id/live/cancel", m.handler((*Manta).handleJobs)) // CancelJob
	mux.GET(baseRoute+"/jobs", m.handler((*Manta).handleJobs))                  // ListJobs
	mux.GET(baseRoute+"/jobs/:id/live/status", m.handler((*Manta).handleJobs))  // GetJob
	mux.GET(baseRoute+"/jobs/:id/live/out", m.handler((*Manta).handleJobs))     // GetJobOutput
	mux.GET(baseRoute+"/jobs/:id/live/in", m.handler((*Manta).handleJobs))      // GetJobInput
	mux.GET(baseRoute+"/jobs/:id/live/fail", m.handler((*Manta).handleJobs))    // GetJobFailures
	mux.GET(baseRoute+"/jobs/:id/live/err", m.handler((*Manta).handleJobs))     // GetJobErrors
}
コード例 #13
0
func (h *Handler) SetRoutes(r *httprouter.Router) {
	r.GET("/connections", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		if r.URL.Query().Get("local_subject") != "" {
			h.FindLocal(w, r, ps)
			return
		}

		if r.URL.Query().Get("remote_subject") != "" && r.URL.Query().Get("provider") != "" {
			h.FindRemote(w, r, ps)
			return
		}

		var ctx = context.Background()
		h.H.WriteErrorCode(ctx, w, r, http.StatusBadRequest, errors.New("Pass either [local_subject] or [remote_subject, provider] as query to this request"))
	})

	r.POST("/connections", h.Create)
	r.GET("/connections/:id", h.Get)
	r.DELETE("/connections/:id", h.Delete)
}
コード例 #14
0
ファイル: router.go プロジェクト: kosuda/golang-web
func setup(router *httprouter.Router) {
	router.GET("/api/user", controller.UserGet)
	router.GET("/api/user/:id", controller.UserGet)
	router.GET("/api/redis/user/:id", controller.RedisUserGet)
	router.GET("/api/redis/user", controller.RedisUserGet)
	router.PUT("/api/user", controller.UserUpsert)
	router.PUT("/api/user/:id", controller.UserUpsert)
	router.PUT("/api/redis/user/:id", controller.RedisUserWrite)
	router.DELETE("/api/user", controller.UserDelete)
	router.DELETE("/api/user/:id", controller.UserDelete)
	router.PATCH("/api/user/:id", controller.UserUpdate)

	// TOTEC
	router.GET("/api/musics", controller.MusicGet)
	router.GET("/api/musics/:id", controller.MusicGet)
	router.POST("/api/musics", controller.MusicUpsert)
	router.PUT("/api/musics/:id", controller.MusicUpsert)
	router.DELETE("/api/musics/:id", controller.MusicDelete)

	router.POST("/api/musics/:id/play", controller.HistoryUpsert)
}
コード例 #15
0
ファイル: server.go プロジェクト: cockroachdb/examples-orms
// RegisterRouter registers a router onto the Server.
func (s *Server) RegisterRouter(router *httprouter.Router) {
	router.GET("/ping", s.ping)

	router.GET("/customer", s.getCustomers)
	router.POST("/customer", s.createCustomer)
	router.GET("/customer/:customerID", s.getCustomer)
	router.PUT("/customer/:customerID", s.updateCustomer)
	router.DELETE("/customer/:customerID", s.deleteCustomer)

	router.GET("/product", s.getProducts)
	router.POST("/product", s.createProduct)
	router.GET("/product/:productID", s.getProduct)
	router.PUT("/product/:productID", s.updateProduct)
	router.DELETE("/product/:productID", s.deleteProduct)

	router.GET("/order", s.getOrders)
	router.POST("/order", s.createOrder)
	router.GET("/order/:orderID", s.getOrder)
	router.PUT("/order/:orderID", s.updateOrder)
	router.DELETE("/order/:orderID", s.deleteOrder)
	router.POST("/order/:orderID/product", s.addProductToOrder)
}
コード例 #16
0
func (h *Handler) SetRoutes(r *httprouter.Router) {
	r.POST(endpoint, h.Create)
	r.GET(endpoint, h.Find)
	r.GET(endpoint+"/:id", h.Get)
	r.DELETE(endpoint+"/:id", h.Delete)
}
コード例 #17
0
ファイル: main.go プロジェクト: MarvinMenzerath/UpAndRunning2
// Setup all routes for API v1
func setupApi1(router *httprouter.Router) {
	router.GET("/api/v1/*all", APIv1.ApiIndexVersion)
	router.POST("/api/v1/*all", APIv1.ApiIndexVersion)
	router.PUT("/api/v1/*all", APIv1.ApiIndexVersion)
	router.DELETE("/api/v1/*all", APIv1.ApiIndexVersion)
}
コード例 #18
0
func Init(router *httprouter.Router) {
	router.GET("/api/todos", todocontroller.GetAll)
	router.POST("/api/todos", todocontroller.NewTodo)
	router.DELETE("/api/todos/:id", todocontroller.RemoveTodo)
}
コード例 #19
0
ファイル: service_http.go プロジェクト: joyent/gosdc
// SetupHTTP attaches all the needed handlers to provide the HTTP API.
func (c *CloudAPI) SetupHTTP(mux *httprouter.Router) {
	baseRoute := "/" + c.ServiceInstance.UserAccount

	mux.NotFound = NotFound{}
	mux.MethodNotAllowed = MethodNotAllowed{}

	// keys
	keysRoute := baseRoute + "/keys"
	mux.GET(keysRoute, c.handler((*CloudAPI).handleListKeys))
	mux.POST(keysRoute, c.handler((*CloudAPI).handleCreateKey))

	// key
	keyRoute := keysRoute + "/:id"
	mux.GET(keyRoute, c.handler((*CloudAPI).handleGetKey))
	mux.DELETE(keyRoute, c.handler((*CloudAPI).handleDeleteKey))

	// images
	imagesRoute := baseRoute + "/images"
	mux.GET(imagesRoute, c.handler((*CloudAPI).handleListImages))

	// image
	imageRoute := imagesRoute + "/:id"
	mux.GET(imageRoute, c.handler((*CloudAPI).handleGetImage))
	mux.POST(imageRoute, c.handler((*CloudAPI).handleCreateImageFromMachine))
	mux.DELETE(imageRoute, c.handler((*CloudAPI).handleDeleteImage))

	// packages
	packagesRoute := baseRoute + "/packages"
	mux.GET(packagesRoute, c.handler((*CloudAPI).handleListPackages))

	// package
	packageRoute := packagesRoute + "/:id"
	mux.GET(packageRoute, c.handler((*CloudAPI).handleGetPackage))

	// machines
	machinesRoute := baseRoute + "/machines"
	mux.GET(machinesRoute, c.handler((*CloudAPI).handleListMachines))
	mux.HEAD(machinesRoute, c.handler((*CloudAPI).handleCountMachines))
	mux.POST(machinesRoute, c.handler((*CloudAPI).handleCreateMachine))

	// machine
	machineRoute := machinesRoute + "/:id"
	mux.GET(machineRoute, c.handler((*CloudAPI).handleGetMachine))
	mux.POST(machineRoute, c.handler((*CloudAPI).handleUpdateMachine))
	mux.DELETE(machineRoute, c.handler((*CloudAPI).handleDeleteMachine))

	// machine metadata
	machineMetadataRoute := machineRoute + "/metadata"
	mux.GET(machineMetadataRoute, c.handler((*CloudAPI).handleGetMachineMetadata))
	mux.POST(machineMetadataRoute, c.handler((*CloudAPI).handleUpdateMachineMetadata))
	mux.DELETE(machineMetadataRoute, c.handler((*CloudAPI).handleDeleteAllMachineMetadata))

	// machine metadata (individual key)
	machineMetadataKeyRoute := machineMetadataRoute + "/:key"
	mux.DELETE(machineMetadataKeyRoute, c.handler((*CloudAPI).handleDeleteMachineMetadata))

	// machine tags
	machineTagsRoute := machineRoute + "/tags"
	mux.GET(machineTagsRoute, c.handler((*CloudAPI).handleListMachineTags))
	mux.POST(machineTagsRoute, c.handler((*CloudAPI).handleAddMachineTags))
	mux.PUT(machineTagsRoute, c.handler((*CloudAPI).handleReplaceMachineTags))
	mux.DELETE(machineTagsRoute, c.handler((*CloudAPI).handleDeleteMachineTags))

	// machine tag
	machineTagRoute := machineTagsRoute + "/:tag"
	mux.GET(machineTagRoute, c.handler((*CloudAPI).handleGetMachineTag))
	mux.DELETE(machineTagRoute, c.handler((*CloudAPI).handleDeleteMachineTag))

	// machine firewall rules
	machineFWRulesRoute := machineRoute + "/fwrules"
	mux.GET(machineFWRulesRoute, c.handler((*CloudAPI).handleMachineFirewallRules))

	// machine NICs
	machineNICsRoute := machineRoute + "/nics"
	mux.GET(machineNICsRoute, c.handler((*CloudAPI).handleListNICs))
	mux.POST(machineNICsRoute, c.handler((*CloudAPI).handleAddNIC))

	// machine NIC
	machineNICRoute := machineNICsRoute + "/:mac"
	mux.GET(machineNICRoute, c.handler((*CloudAPI).handleGetNIC))
	mux.DELETE(machineNICRoute, c.handler((*CloudAPI).handleRemoveNIC))

	// firewall rules
	firewallRulesRoute := baseRoute + "/fwrules"
	mux.GET(firewallRulesRoute, c.handler((*CloudAPI).handleListFirewallRules))
	mux.POST(firewallRulesRoute, c.handler((*CloudAPI).handleCreateFirewallRule))

	// firewall rule
	firewallRuleRoute := firewallRulesRoute + "/:id"
	mux.GET(firewallRuleRoute, c.handler((*CloudAPI).handleGetFirewallRule))
	mux.POST(firewallRuleRoute, c.handler((*CloudAPI).handleUpdateFirewallRule))
	mux.DELETE(firewallRuleRoute, c.handler((*CloudAPI).handleDeleteFirewallRule))
	mux.POST(firewallRuleRoute+"/enable", c.handler((*CloudAPI).handleEnableFirewallRule))
	mux.POST(firewallRuleRoute+"/disable", c.handler((*CloudAPI).handleDisableFirewallRule))

	// networks
	networksRoute := baseRoute + "/networks"
	mux.GET(networksRoute, c.handler((*CloudAPI).handleListNetworks))

	// network
	networkRoute := networksRoute + "/:id"
	mux.GET(networkRoute, c.handler((*CloudAPI).handleGetNetwork))

	// fabric VLANs
	fabricVLANsRoute := baseRoute + "/fabrics/:fabric/vlans"
	mux.GET(fabricVLANsRoute, c.handler((*CloudAPI).handleListFabricVLANs))
	mux.POST(fabricVLANsRoute, c.handler((*CloudAPI).handleCreateFabricVLAN))

	// fabric VLAN
	fabricVLANRoute := fabricVLANsRoute + "/:id"
	mux.GET(fabricVLANRoute, c.handler((*CloudAPI).handleGetFabricVLAN))
	mux.PUT(fabricVLANRoute, c.handler((*CloudAPI).handleUpdateFabricVLAN))
	mux.DELETE(fabricVLANRoute, c.handler((*CloudAPI).handleDeleteFabricVLAN))

	// fabric VLAN networks
	fabricVLANNetworksRoute := fabricVLANRoute + "/networks"
	mux.GET(fabricVLANNetworksRoute, c.handler((*CloudAPI).handleListFabricNetworks))
	mux.POST(fabricVLANNetworksRoute, c.handler((*CloudAPI).handleCreateFabricNetwork))

	// fabric VLAN network
	fabricVLANNetworkRoute := fabricVLANNetworksRoute + "/:network"
	mux.GET(fabricVLANNetworkRoute, c.handler((*CloudAPI).handleGetFabricNetwork))
	mux.DELETE(fabricVLANNetworkRoute, c.handler((*CloudAPI).handleDeleteFabricNetwork))

	// services
	servicesRoute := baseRoute + "/services"
	mux.GET(servicesRoute, c.handler((*CloudAPI).handleGetServices))
}
コード例 #20
0
ファイル: handler.go プロジェクト: cmars/shadowfax
// Register sets up endpoint routing for a shadowfax server.
func (h *Handler) Register(r *httprouter.Router) {
	r.GET("/publickey", h.publicKey)
	r.DELETE("/inbox/:recipient", h.pop)
	r.POST("/outbox/:sender", h.push)
}
コード例 #21
0
ファイル: main.go プロジェクト: gradientzoo/gradientzoo
func DELETE(r *httprouter.Router, path string, handler Handler) {
	r.DELETE(path, handle(handler))
}
コード例 #22
0
ファイル: handler.go プロジェクト: jemacom/hydra
func (h *Handler) SetRoutes(r *httprouter.Router) {
	r.GET(ClientsHandlerPath, h.GetAll)
	r.POST(ClientsHandlerPath, h.Create)
	r.GET(ClientsHandlerPath+"/:id", h.Get)
	r.DELETE(ClientsHandlerPath+"/:id", h.Delete)
}
コード例 #23
0
ファイル: crud.go プロジェクト: ably-forks/flynn
func crud(r *httprouter.Router, resource string, example interface{}, repo Repository) {
	resourceType := reflect.TypeOf(example)
	prefix := "/" + resource

	r.POST(prefix, httphelper.WrapHandler(func(ctx context.Context, rw http.ResponseWriter, req *http.Request) {
		thing := reflect.New(resourceType).Interface()
		if err := httphelper.DecodeJSON(req, thing); err != nil {
			respondWithError(rw, err)
			return
		}

		if err := schema.Validate(thing); err != nil {
			respondWithError(rw, err)
			return
		}

		if err := repo.Add(thing); err != nil {
			respondWithError(rw, err)
			return
		}
		httphelper.JSON(rw, 200, thing)
	}))

	lookup := func(ctx context.Context) (interface{}, error) {
		params, _ := ctxhelper.ParamsFromContext(ctx)
		return repo.Get(params.ByName(resource + "_id"))
	}

	singletonPath := prefix + "/:" + resource + "_id"
	r.GET(singletonPath, httphelper.WrapHandler(func(ctx context.Context, rw http.ResponseWriter, _ *http.Request) {
		thing, err := lookup(ctx)
		if err != nil {
			respondWithError(rw, err)
			return
		}
		httphelper.JSON(rw, 200, thing)
	}))

	r.GET(prefix, httphelper.WrapHandler(func(ctx context.Context, rw http.ResponseWriter, _ *http.Request) {
		list, err := repo.List()
		if err != nil {
			respondWithError(rw, err)
			return
		}
		httphelper.JSON(rw, 200, list)
	}))

	if remover, ok := repo.(Remover); ok {
		r.DELETE(singletonPath, httphelper.WrapHandler(func(ctx context.Context, rw http.ResponseWriter, _ *http.Request) {
			_, err := lookup(ctx)
			if err != nil {
				respondWithError(rw, err)
				return
			}
			params, _ := ctxhelper.ParamsFromContext(ctx)
			if err = remover.Remove(params.ByName(resource + "_id")); err != nil {
				respondWithError(rw, err)
				return
			}
			rw.WriteHeader(200)
		}))
	}
}