crud

module
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2023 License: MIT

README

header-image

crud

English | 机翻中文

Go Reference Badge Go Report Badge

Crud is a golang package that helps writing CRUD servers. With this package, all you need is models, while all the rest is done for you automatically.

crud = GORM + Gin + Logrus + Viper + automatic CRUD service

Get started

  1. get the package:
go get -u github.com/cdfmlr/crud
  1. all you need are models, and register them in orm & router:
package main

import (
	"github.com/cdfmlr/crud/orm"
	"github.com/cdfmlr/crud/router"
)

type Todo struct {
	orm.BasicModel
	Title  string `json:"title"`
	Detail string `json:"detail"`
	Done   bool   `json:"done"`
}

type Project struct {
	orm.BasicModel
	Title string  `json:"title"`
	Todos []*Todo `json:"todos" gorm:"many2many:project_todos"`
}

func main() {
	orm.ConnectDB(orm.DBDriverSqlite, "todolist.db")
	orm.RegisterModel(Todo{}, Project{})

	r := router.NewRouter()
	router.Crud[Todo](r, "/todos")
	router.Crud[Project](r, "/projects",
		router.CrudNested[Project, Todo]("todos"),
	)

	r.Run(":8086")
}

These 32 lines of code make it an available RESTful API service with 13 endpoints:

# api to todos
GET    /todos
GET    /todos/:TodoID
POST   /todos
PUT    /todos/:TodoID
DELETE /todos/:TodoID

# api to projects
GET    /projects
GET    /projects/:ProjectID
POST   /projects
PUT    /projects/:ProjectID
DELETE /projects/:ProjectID

# api to nested todos in a project
GET    /projects/:ProjectID/todos
POST   /projects/:ProjectID/todos
DELETE /projects/:ProjectID/todos/:TodoID

Let's explain it.

orm

crud/orm is an ORM package works as crud's DAO layer. It's a wrapper of GORM with responsibility for database connection and auto migrate.

orm.ConnectDB is used to connect to a database. It's a wrapper of gorm.Open. And orm.RegisterModel is used to register your models, which calls gorm.AutoMigrate to build the tables.

orm package also defines a Model interface. Crud can only automatically generate CRUD services for models that implement this interface. orm.BasicModel is a basic implementation of this interface. It's a wrapper of gorm.Model, which defines an auto-incrementing primary key and soft delete support:

type BasicModel struct {
    ID        uint `gorm:"primary_key"`
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt *time.Time `sql:"index"`
}

In most cases, you can just embed orm.BasicModel to your model. It's a good starting point.

router

crud/router is a package that helps you to generate CRUD services based on gin.

It provides a router.NewRouter() function to create a new gin router.

And the magic is router.Crud[Todo](r, "/todos"), that will automatically make REST APIs to the model Todo at relative path /todos:

GET /todos            # get todos list

GET /todos/:id        # get a todo by id

POST /todos           # create a new todo record
{
    "title": "clean my room"
}

PUT /todos/:id        # update a todo record
{
    "done": true
}

DELETE /todos/:id     # delete a todo record

BTW, the type parameter Todo is required. It's not inferable for the compiler.

router.CrudNested[Project, Todo]("todos") will create nested APIs to the model Todo in the model Project, that is, CRUD for the Project.Todos field:

GET    /projects/:ProjectID/todos          # get associated todos list

POST   /projects/:ProjectID/todos          # create new associated relationship
{
    "title": "clean my kitchen"
    "detail": "rm -rf bin; mv cooktop/* cupboard"
}

DELETE /projects/:ProjectID/todos/:TodoID  # delete an associated relationship

Next steps

For an extremely simple project, like todolist above, using crud/orm and crud/router together is enough to make API jobs done. But for a more real-world case, you may want to use lower level parts of crud to build your own CRUD API services:

  • crud/controller: Package controller implements model based generic CRUD controllers (i.e. http handlers) to handle create / read / update / delete requests from http clients.
  • crud/service: Package service implements the basic CRUD operations for models.
  • crud/config is a package that helps you to read configuration into a structure based "ConfigModel". It's a wrapper of viper
  • crud/log is a package that helps you to log your application. It's a wrapper of logrus

Documents:

Examples:

  • sshman is a more real world example of how crud can help you build a CRUD REST API project fast and easily. Please check it out.

How it works

The implementation of crud is inspired by the layered MVC architecture:

curd architecture

Layer Description
router define REST APIs
controller handles the HTTP requests (GET/POST/PUT/DELETE)
service business logic (Create/Read/Update/Delete)
orm DAO: R/Ws to the database

Each layer is a package. And with generics and reflection in Go, crud achieves generic implementations for each layer.

TODOs

  • tests for services and controllers
  • updates depended Gin/GORM/... packages automaticly (dependabot)
  • ...

MIT License

Copyright (c) 2022 CDFMLR

Directories

Path Synopsis
Package config implements a model based config system for your app.
Package config implements a model based config system for your app.
Package controller implements model based generic CRUD controllers (i.e.
Package controller implements model based generic CRUD controllers (i.e.
Package orm wraps the gorm to provide a simple ORM layer.
Package orm wraps the gorm to provide a simple ORM layer.
pkg
Package router is used to create a gin router and add automatic CRUD routes for your models.
Package router is used to create a gin router and add automatic CRUD routes for your models.
Package service implements the basic CRUD operations for models.
Package service implements the basic CRUD operations for models.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL