So... I'm creating a RESTful API for my idea using Gin framework and I've came into the following problem - Let's say that I've got the following endpoints:
/a/:id/*action /b/:id/*action /c/:id/*action
So, obviously, when I'm not giving any action then I want to return the data for the given ID. Meaning, I'm doing nothing but querying some data and returning it, this means that the functionality is basically the same and only the returned data is different.
Here's an example code of mine -
func GetBusiness(c *gin.Context) {
businessID, err := strconv.Atoi(c.Param("id"))
if businessID == 0 || err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "errorMessage": "Missing ID"})
}
business := &Business{}
business, err = business.Get(businessID)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"success": false, "errorMessage": "Business not found"})
}
c.JSON(http.StatusOK, business)
}
So, obviously, business can become user or anything else. So, after this long exposition, my question to you goers, is, how can I prevent code duplication in this kind of situation? I've tried using an interface but I'm still struggling with the OO nature of Go, so I would really appriciate any help.
Thanks in advance!
There are a few things you can do to reduce code duplication, but unfortunately, you will always be writing some boilerplate in go, because of it's explicit error handling and lack of OOP-ness. (which is not necessarily a bad thing!).
So my only suggestions at the moment is to put common functionality in middleware handlers and restructure your code a litte, for example:
parseIdMiddleware := func(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if businessID == 0 || err != nil {
c.AbortWithError(http.StatusBadRequest, errors.New("Missing ID"))
return
}
c.Set("id", id)
}
...
gin.Use(gin.ErrorLogger(), parseIdMiddleware)
and rewrite your handlers to
func GetBusiness(c *gin.Context) {
id := c.MustGet("id").(int)
business, err := store.GetBusiness(id)
if err != nil {
c.AbortWithError(http.StatusBadRequest, err)
return // don't forget this!
}
c.JSON(http.StatusOK, business)
}
And as always, read other people's code! I recommend https://github.com/drone/drone. That should give you a pretty good overview of how to structure your code.