第一版本
每个资源的每个方法都是分开的
资源和资源是分开的
资源的方法和资源的方法也是不相干的
示例中涉及的资源是 task和service
package main
import (
"github.com/gin-gonic/gin"
)
// task结构体
type Task struct {
Name string
Description string
}
// 定义task需要的方法
type TaskRegistry struct {
}
func (t *TaskRegistry) ListTasks() ([]Task, error) {
return []Task{{
Name: "task",
Description: "task test",
}}, nil
}
func (t *TaskRegistry) CreateTask(task Task) error {
return nil
}
// service结构体
type Service struct {
Name string
Description string
}
// 定义service需要的方法
type ServiceRegistry struct {
}
func (s *ServiceRegistry) ListServices() ([]Service, error) {
return []Service{{
Name: "service",
Description: "service test",
}}, nil
}
func (s *ServiceRegistry) CreateService(task Service) error {
return nil
}
// task API 处理函数
func createTaskHandler(c *gin.Context) {
var task Task
if err := c.ShouldBindJSON(&task); err != nil {
c.JSON(400, gin.H{"error": "Bad Request"})
return
}
taskRegistry := TaskRegistry{}
err := taskRegistry.CreateTask(task)
if err != nil {
c.JSON(500, gin.H{"error": "Failed to create task"})
return
}
c.JSON(201, gin.H{"message": "Task created successfully"})
}
func listTasksHandler(c *gin.Context) {
taskRegistry := TaskRegistry{}
tasks, err := taskRegistry.ListTasks()
if err != nil {
c.JSON(500, gin.H{"error": "Failed to list tasks"})
return
}
c.JSON(200, tasks)
}
// service API 处理函数
func listServicesHandler(c *gin.Context) {
serviceRegistry := ServiceRegistry{}
services, err := serviceRegistry.ListServices()
if err != nil {
c.JSON(500, gin.H{"error": "Failed to list tasks"})
return
}
c.JSON(200, services)
}
func createServicesHandler(c *gin.Context) {
var service Service
if err := c.ShouldBindJSON(&service); err != nil {
c.JSON(400, gin.H{"error": "Bad Request"})
return
}
ServiceRegistry := ServiceRegistry{}
err := ServiceRegistry.CreateService(service)
if err != nil {
c.JSON(500, gin.H{"error": "Failed to create service"})
return
}
c.JSON(201, gin.H{"message": "Service created successfully"})
}
func main() {
// 初始化 Gin Web 框架
r := gin.Default()
// 注册 API 路由
r.POST("/tasks", createTaskHandler)
r.GET("/tasks", listTasksHandler)
r.GET("/services", listServicesHandler)
r.POST("/services", createServicesHandler)
// 启动 Web 服务器
r.Run(":8080")
}
第二版本
抽象资源
task和service都属于资源,那么对待资源应该有统一的处理方式,只需要区分不同的资源执行相应资源的方法就行
package main
import (
"github.com/gin-gonic/gin"
)
// task结构体
type Task struct {
Name string
Description string
}
// 定义task需要的方法
type TaskRegistry struct {
}
func (t *TaskRegistry) ListTasks() ([]Task, error) {
return []Task{{
Name: "task",
Description: "task test",
}}, nil
}
func (t *TaskRegistry) CreateTask(task Task) error {
return nil
}
// service结构体
type Service struct {
Name string
Description string
}
// 定义service需要的方法
type ServiceRegistry struct {
}
func (s *ServiceRegistry) ListServices() ([]Service, error) {
return []Service{{
Name: "service",
Description: "service test",
}}, nil
}
func (s *ServiceRegistry) CreateService(task Service) error {
return nil
}
func main() {
// 初始化 Gin Web 框架
r := gin.Default()
// 注册 API 路由
//r.POST("/tasks", createTaskHandler)
//r.GET("/tasks", listTasksHandler)
//r.GET("/services", listServicesHandler)
//r.POST("/services", createServicesHandler)
r.Any("/resource/:type", restHandler)
// 启动 Web 服务器
r.Run(":8080")
}
func restHandler(c *gin.Context) {
resourceType := c.Param("type")
switch resourceType {
case "task":
if c.Request.Method == "GET" {
taskRegistry := TaskRegistry{}
tasks, err := taskRegistry.ListTasks()
if err != nil {
c.JSON(500, gin.H{"error": "Failed to list tasks"})
return
}
c.JSON(200, tasks)
} else if c.Request.Method == "POST" {
var task Task
if err := c.ShouldBindJSON(&task); err != nil {
c.JSON(400, gin.H{"error": "Bad Request"})
return
}
taskRegistry := TaskRegistry{}
err := taskRegistry.CreateTask(task)
if err != nil {
c.JSON(500, gin.H{"error": "Failed to create task"})
return
}
c.JSON(201, gin.H{"message": "Task created successfully"})
}
case "service":
if c.Request.Method == "GET" {
serviceRegistry := ServiceRegistry{}
services, err := serviceRegistry.ListServices()
if err != nil {
c.JSON(500, gin.H{"error": "Failed to list tasks"})
return
}
c.JSON(200, services)
} else if c.Request.Method == "POST" {
var service Service
if err := c.ShouldBindJSON(&service); err != nil {
c.JSON(400, gin.H{"error": "Bad Request"})
return
}
ServiceRegistry := ServiceRegistry{}
err := ServiceRegistry.CreateService(service)
if err != nil {
c.JSON(500, gin.H{"error": "Failed to create service"})
return
}
c.JSON(201, gin.H{"message": "Service created successfully"})
}
}
}
第三版本
既抽象资源又抽象资源的方法
步骤总结:
比如 需要针对service和task这两个资源写一些方法
1、对资源的dao层(数据库操作)进行封装,这块内容可以单独放在一个文件中,套路就是定义个结构体然后给这个结构体增加方法
2、抽象资源的公共方法,比如资源都得进行增删改查,然后就定义一个接口interface,规定都有那些方法(接口)
3、每个资源都要去实现这个接口中的方法,套路也是定义个结构体,然后去实现接口中的方法
4、给资源们整一个统一入口,因为都是资源,可以理解为都是一个东西,那就有一个入口就行了,比如文中的
r.Any("/resource/:type", restHandler) // 资源统一入口
这里都输入工厂模式了,统一的入口然后根据不同的资源去执行资源自己的方法
package main
import (
"github.com/gin-gonic/gin"
)
// task结构体 定义task的一些基本信息
type Task struct {
Name string
Description string
}
// 对task dao层(数据库操作)的一些封装
type TaskRegistry struct{}
func (t *TaskRegistry) ListTasks() ([]Task, error) {
return []Task{{
Name: "task",
Description: "task test",
}}, nil
}
func (t *TaskRegistry) CreateTask(task Task) error {
return nil
}
// 定义结构体去实现这个接口 task这个资源对这个接口的具体实现 对task http层接口的封装
type TaskStorage struct{}
func (t *TaskStorage) List(c *gin.Context) {
taskRegistry := TaskRegistry{}
tasks, err := taskRegistry.ListTasks()
if err != nil {
c.JSON(500, gin.H{"error": "Failed to list tasks"})
return
}
c.JSON(200, tasks)
}
func (t *TaskStorage) Create(c *gin.Context) {
var task Task
if err := c.ShouldBindJSON(&task); err != nil {
c.JSON(400, gin.H{"error": "Bad Request"})
return
}
taskRegistry := TaskRegistry{}
err := taskRegistry.CreateTask(task)
if err != nil {
c.JSON(500, gin.H{"error": "Failed to create task"})
return
}
c.JSON(201, gin.H{"message": "Task created successfully"})
}
// service结构体 定义service的一些基本信息
type Service struct {
Name string
Description string
}
// 定义service需要的方法 对service dao层的封装
type ServiceRegistry struct{}
func (s *ServiceRegistry) ListServices() ([]Service, error) {
return []Service{{
Name: "service",
Description: "service test",
}}, nil
}
func (s *ServiceRegistry) CreateService(task Service) error {
return nil
}
// service资源对这个接口的具体实现 对service http层的一些封装
type ServiceStorage struct{}
func (s *ServiceStorage) List(c *gin.Context) {
serviceRegistry := ServiceRegistry{}
services, err := serviceRegistry.ListServices()
if err != nil {
c.JSON(500, gin.H{"error": "Failed to list tasks"})
return
}
c.JSON(200, services)
}
func (s *ServiceStorage) Create(c *gin.Context) {
var service Service
if err := c.ShouldBindJSON(&service); err != nil {
c.JSON(400, gin.H{"error": "Bad Request"})
return
}
ServiceRegistry := ServiceRegistry{}
err := ServiceRegistry.CreateService(service)
if err != nil {
c.JSON(500, gin.H{"error": "Failed to create service"})
return
}
c.JSON(201, gin.H{"message": "Service created successfully"})
}
// 定义接口 方法的抽象 只要是资源都应该有这两个方法 所有资源方法的抽象接口
type handleStorage interface {
List(c *gin.Context)
Create(c *gin.Context)
}
// 资源的统一入口handler
func restHandler(c *gin.Context) {
// 工厂模式 设置成map 根据不同的key=>资源 掉用资源的方法
m := map[string]handleStorage{
"task": &TaskStorage{},
"service": &ServiceStorage{},
}
resourceType := c.Param("type")
switch c.Request.Method {
case "GET":
m[resourceType].List(c)
case "POST":
m[resourceType].Create(c)
}
}
func main() {
r := gin.Default()
r.Any("/resource/:type", restHandler) // 资源的统一入口
r.Run(":8080")
}
服务器租用托管,机房租用托管,主机租用托管,https://www.e1idc.com