DEV Community

Seth Phat
Seth Phat

Posted on

4 4

Go Gin&Gorm: Route Model Binding

Howdy guys,

From my daily work, I'm using PHP & Laravel. One of the feature that I really like & helpful is "Route Model Binding".

Basically, you just need to define your routes and add the Model into the path, magic happens, you'll:

  • Get the Model instance and ready-to-use in the Controllers/Middlewares/Requests.
  • Receive 404 not found if the record didn't exists.

With Go, we have to build things for our needs, indeed.

Inspired by Laravel Route Model Binding, I built a Middleware for Gin which will help me to achieve that and I don't have to do Find then return error if not exists from the Controller. Extracted that to another layer.

Repo for the Middleware - sethsandaru/go-route-model-binding

Please give it a ⭐ if you actually like/going to use it πŸ’–

Feature

Eg: users/:user => Find the User model instance

  • If exists: bind it to the Gin's context via c.Set so you can retrieve it
  • If not: return 404 resource not found

It definitely makes our life easier, doesn't it? I hate to do like: "find record, not exists/error => return 404" in the controller, cuz it's not fun and make my controller's methods a bit longer

  • Q: Does it support multiple params eg: "users/:user/update-categories/:category"?
  • A: Yes

Mapping - Explicit Binding

Since it won't be as smart as Laravel's way. We need to define a map in order to map your route params with a gORM model.

var routeModelMapping = map[string]modelMapping{
    "entity": makeModelMapping(&models.Entity{}, "uuid"),
    "user": makeModelMapping(&model.User{}, "uuid"),
    // ...
}
Enter fullscreen mode Exit fullscreen mode

Access from Controllers

I love the term Controller and always using MVC in all of my applications.

func (controller *entityController) Show(c *gin.Context) {
    entity, _ := c.Get("entity")
    respondOk(c, entity)
}
Enter fullscreen mode Exit fullscreen mode
func (controller *userController) Show(c *gin.Context) {
    user, _ := c.Get("user")
    respondOk(c, user)
}
Enter fullscreen mode Exit fullscreen mode

In order to get the correct type, we have to do typeAssertion - guide here

Conclusions

  • PROs:
    • Automatically retrieve Model instances using gORM
    • 404 not found will be returned if instance not found
    • Extracted the find and check exists out of the Controller
  • CONs:
    • Have to do typeAssertion in order to get the real type

Hopefully you'll like this, just like me hehee.

Once again, here is the repo Middleware - sethsandaru/go-route-model-binding

Please give it a ⭐ if you actually like/going to use it πŸ’–

I'm using that Middleware from my open-source project (WIP) Pheasant - Dynamic CRUD Management

Have a nice weekend and happy go-coding!

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More