Turf
Turf is a library that works with Surf to generate controllers.
Rest Controllers
The subpackage rest
inside of this repository defines the types of controllers to handle various model types, as defined in Carrot's Restful API Spec.
Base Models
Base Models are models that can be accessed directly, and are not dependent on the relation of any models.
Full Definition
func NewPostsController() *rest.BaseController {
return &rest.BaseController{
GetModel: func() surf.Model {
return models.NewPost()
},
}
}
Registering this controller enables the following endpoints:
[POST] /posts
[GET] /posts
[GET] /posts/:id
[PUT] /posts/:id
[DELETE] /posts/:id
One-to-One Models
One to one models are models(a) who exist only to be associated to another model(b), and the model(b) can only reference a single model(a).
Full Definition
func NewPostsVideoController() *rest.OneToOneController {
return &rest.OneToOneController{
NestedModelNameSingular: "video",
ForeignReference: "video_id", // The value in the BaseModel that references the NestedModel
GetBaseModel: func() surf.Model {
return models.NewPost()
},
GetNestedModel: func() surf.Model {
return models.NewVideo()
},
}
}
Registering this controller enables the following endpoints:
[POST] /posts/:id/video
[GET] /posts/:id/video
[PUT] /posts/:id/video
[DELETE] /posts/:id/video
One-to-Many Models
One to many models are models(a) that exist to be associated to another model(b), but model(b) can reference multiple models(a).
Full Definition
func NewAuthorPostsController() *rest.OneToManyController {
return &rest.OneToManyController{
NestedForeignReference: "author_id", // The value in the NestedModel that references the BaseModel
GetBaseModel: func() surf.Model {
return models.NewAuthor()
},
GetNestedModel: func() surf.Model {
return models.NewPost()
},
BelongsTo: func(baseModel, nestedModel surf.Model) bool {
return nestedModel.(*models.Post).AuthorId == baseModel.(*models.Author).Id
},
}
}
Registering this controller enables the following endpoints:
[POST] /authors/:id/posts
[GET] /authors/:id/posts
[GET] /authors/:id/posts/:id
[PUT] /authors/:id/posts/:id
[DELETE] /authors/:id/posts/:id
Many-to-Many Models
Many to many models are models who are responsible for associating two other models (model(a) to model(b)). These models can contain additional information about the association, but that is optional.
Full Definition
func NewPostTagsController() *rest.ManyToManyController {
return &rest.ManyToManyController{
BaseModelForeignReference: "post_id", // The BaseModel reference in the RelationModel
NestedModelForeignReference: "tag_id", // The NestedModel reference in the RelationModel
GetBaseModel: func() surf.Model {
return models.NewPost()
},
GetNestedModel: func() surf.Model {
return models.NewTag()
},
GetRelationModel: func() surf.Model {
return models.NewPostTag()
},
}
}
Registering this controller enables the following endpoints:
[POST] /posts/:id/tags/:id
[GET] /posts/:id/tags
[GET] /posts/:id/tags/:id
[PUT] /posts/:id/tags/:id
[DELETE] /posts/:id/tags/:id
Lifecycle Hooks
All Rest models have a field named LifecycleHooks
that can be set to give control at a certain point in the lifecycle of a method.
Usage is detailed in this file.
Method Whitelists
All Rest models have a field named MethodWhiteList
that can be set with a slice of strings.
rest.BaseController{
GetModel: func() surf.Model {
return models.NewPost()
},
MethodWhiteList: []string{turf.INDEX, turf.SHOW},
}
If MethodWhiteList
is not set, all supported methods get registered upon calling controller.Register
.
Controller Registration
All Controllers have a Register
method that will automatically register the controller to a httprouter.Router.
This also allows middleware to be passed in.
router := httprouter.New()
controllers.NewPostsController().Register(router, middleware.Global)
http.ListenAndServe(":8080", router)
License
MIT