Example #1
0
func (c *TestController) Path() string {
	return paths.PathPrefixForClass(c)
}
Example #2
0
File: mapping.go Project: smw/goweb
// MapController maps a controller to a specified path prefix.
//
// For more information, see goweb.MapController.
func (h *HttpHandler) MapController(options ...interface{}) error {

	var path string
	var controller interface{}

	switch len(options) {
	case 0: // ()
		// no arguments is an error
		panic("goweb: Cannot call MapController with no arguments")
	case 1: // (controller)
		if restfulController, ok := options[0].(controllers.RestfulController); ok {
			controller = restfulController
			path = restfulController.Path()
		} else {
			// use the default path
			controller = options[0]
			path = paths.PathPrefixForClass(options[0])
		}
		break
	case 2: // (path, controller)
		path = options[0].(string)
		controller = options[1]
	}

	// get the specialised paths that we might need
	pathWithID := stewstrings.MergeStrings(path, "/{", RestfulIDParameterName, "}")         // e.g.  people/123
	pathWithOptionalID := stewstrings.MergeStrings(path, "/[", RestfulIDParameterName, "]") // e.g.  people/[123]

	// get the HTTP methods that we will end up mapping
	collectiveMethods := controllers.OptionsListForResourceCollection(controller)
	singularMethods := controllers.OptionsListForSingleResource(controller)

	// BeforeHandler
	if beforeController, ok := controller.(controllers.BeforeHandler); ok {

		// map the collective before handler
		h.MapBefore(collectiveMethods, path, beforeController.Before)

		// map the singular before handler
		h.MapBefore(singularMethods, pathWithID, beforeController.Before)

	}

	// AfterHandler
	if afterController, ok := controller.(controllers.AfterHandler); ok {

		// map the collective after handler
		h.MapAfter(collectiveMethods, path, afterController.After)

		// map the singular after handler
		h.MapAfter(singularMethods, pathWithID, afterController.After)

	}

	// POST /resource  -  Create
	if restfulController, ok := controller.(controllers.RestfulCreator); ok {
		h.Map(http.MethodPost, path, restfulController.Create)
	}

	// GET /resource/{id}  -  Read
	if restfulController, ok := controller.(controllers.RestfulReader); ok {
		h.Map(http.MethodGet, pathWithID, func(ctx context.Context) error {
			return restfulController.Read(ctx.PathParams().Get(RestfulIDParameterName).(string), ctx)
		})
	}

	// GET /resource  -  ReadMany
	if restfulController, ok := controller.(controllers.RestfulManyReader); ok {
		h.Map(http.MethodGet, path, restfulController.ReadMany)
	}

	// DELETE /resource/{id}  -  Delete
	if restfulController, ok := controller.(controllers.RestfulDeletor); ok {
		h.Map(http.MethodDelete, pathWithID, func(ctx context.Context) error {
			return restfulController.Delete(ctx.PathParams().Get(RestfulIDParameterName).(string), ctx)
		})
	}

	// DELETE /resource  -  DeleteMany
	if restfulController, ok := controller.(controllers.RestfulManyDeleter); ok {
		h.Map(http.MethodDelete, path, restfulController.DeleteMany)
	}

	// PUT /resource/{id}  -  Update
	if restfulController, ok := controller.(controllers.RestfulUpdater); ok {
		h.Map(http.MethodPut, pathWithID, func(ctx context.Context) error {
			return restfulController.Update(ctx.PathParams().Get(RestfulIDParameterName).(string), ctx)
		})
	}

	// PUT /resource  -  UpdateMany
	if restfulController, ok := controller.(controllers.RestfulManyUpdater); ok {
		h.Map(http.MethodPut, path, restfulController.UpdateMany)
	}

	// POST /resource/{id}  -  Replace
	if restfulController, ok := controller.(controllers.RestfulReplacer); ok {
		h.Map(http.MethodPost, pathWithID, func(ctx context.Context) error {
			return restfulController.Replace(ctx.PathParams().Get(RestfulIDParameterName).(string), ctx)
		})
	}

	// HEAD /resource/[id]  -  Head
	if restfulController, ok := controller.(controllers.RestfulHead); ok {
		h.Map(http.MethodHead, pathWithOptionalID, restfulController.Head)
	}

	// OPTIONS /resource/[id]  -  Options
	if restfulController, ok := controller.(controllers.RestfulOptions); ok {

		h.Map(http.MethodOptions, pathWithOptionalID, restfulController.Options)

	} else {

		// use the default options implementation

		h.Map(http.MethodOptions, path, func(ctx context.Context) error {
			ctx.HttpResponseWriter().Header().Set("Allow", strings.Join(collectiveMethods, ","))
			ctx.HttpResponseWriter().WriteHeader(200)
			return nil
		})

		h.Map(http.MethodOptions, pathWithID, func(ctx context.Context) error {
			ctx.HttpResponseWriter().Header().Set("Allow", strings.Join(singularMethods, ","))
			ctx.HttpResponseWriter().WriteHeader(200)
			return nil
		})

	}

	// everything ok
	return nil

}