Go实战 | 使用Go-Fiber采用分层架构搭建一个简单的Web服务
前言
📢博客主页:程序源⠀-CSDN博客
📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!
一、环境准备、示例介绍
Go语言安装,GoLand编辑器
这个示例实现了一个简单的待办事项(todo)管理系统。
目录详情
新建一个fiber-todos文件夹,在目录中新建如下文件
二、代码编写
采用分层架构搭建一个简单的Web服务有助于提高代码的可维护性和可扩展性。我们将把应用程序分为以下几个层次:
-
Handler(处理器层):处理HTTP请求。
-
Service(服务层):包含业务逻辑。
-
Repository(仓库层):处理数据访问逻辑。
-
Model(模型层):定义数据结构。
2.1 Handler(处理器层)
package handler import ( "fiber-todos/model" "fiber-todos/service" "github.com/gofiber/fiber/v2" ) type TodoHandler struct { service service.TodoService } func NewTodoHandler(service service.TodoService) *TodoHandler { return &TodoHandler{service: service} } func (h *TodoHandler) GetTodos(c *fiber.Ctx) error { todos := h.service.GetAllTodos() return c.JSON(todos) } func (h *TodoHandler) GetTodoByID(c *fiber.Ctx) error { id := c.Params("id") todo, found := h.service.GetTodoByID(id) if !found { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Todo not found"}) } return c.JSON(todo) } func (h *TodoHandler) CreateTodo(c *fiber.Ctx) error { todo := new(model.Todo) if err := c.BodyParser(todo); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Cannot parse JSON"}) } createdTodo := h.service.CreateTodo(*todo) return c.Status(fiber.StatusCreated).JSON(createdTodo) } func (h *TodoHandler) UpdateTodo(c *fiber.Ctx) error { id := c.Params("id") todo := new(model.Todo) if err := c.BodyParser(todo); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Cannot parse JSON"}) } updatedTodo, found := h.service.UpdateTodo(id, *todo) if !found { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Todo not found"}) } return c.JSON(updatedTodo) } func (h *TodoHandler) DeleteTodo(c *fiber.Ctx) error { id := c.Params("id") deleted := h.service.DeleteTodo(id) if !deleted { return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "Todo not found"}) } return c.SendStatus(fiber.StatusNoContent) }
2.2 Service(服务层)
package service import ( "fiber-todos/model" "fiber-todos/repository" ) type TodoService interface { GetAllTodos() []model.Todo GetTodoByID(id string) (model.Todo, bool) CreateTodo(todo model.Todo) model.Todo UpdateTodo(id string, todo model.Todo) (model.Todo, bool) DeleteTodo(id string) bool } type todoService struct { repo repository.TodoRepository } func NewTodoService(repo repository.TodoRepository) TodoService { return &todoService{repo: repo} } func (s *todoService) GetAllTodos() []model.Todo { return s.repo.GetAll() } func (s *todoService) GetTodoByID(id string) (model.Todo, bool) { return s.repo.GetByID(id) } func (s *todoService) CreateTodo(todo model.Todo) model.Todo { return s.repo.Create(todo) } func (s *todoService) UpdateTodo(id string, todo model.Todo) (model.Todo, bool) { return s.repo.Update(id, todo) } func (s *todoService) DeleteTodo(id string) bool { return s.repo.Delete(id) }
2.3 Repository(仓库层)
package repository import ( "fiber-todos/model" "github.com/google/uuid" ) type TodoRepository interface { GetAll() []model.Todo GetByID(id string) (model.Todo, bool) Create(todo model.Todo) model.Todo Update(id string, todo model.Todo) (model.Todo, bool) Delete(id string) bool } type InMemoryTodoRepository struct { todos []model.Todo } func NewInMemoryTodoRepository() TodoRepository { return &InMemoryTodoRepository{ todos: []model.Todo{}, } } func (r *InMemoryTodoRepository) GetAll() []model.Todo { return r.todos } func (r *InMemoryTodoRepository) GetByID(id string) (model.Todo, bool) { for _, todo := range r.todos { if todo.ID == id { return todo, true } } return model.Todo{}, false } func (r *InMemoryTodoRepository) Create(todo model.Todo) model.Todo { todo.ID = uuid.New().String() r.todos = append(r.todos, todo) return todo } func (r *InMemoryTodoRepository) Update(id string, updatedTodo model.Todo) (model.Todo, bool) { for i, todo := range r.todos { if todo.ID == id { r.todos[i].Title = updatedTodo.Title r.todos[i].Done = updatedTodo.Done return r.todos[i], true } } return model.Todo{}, false } func (r *InMemoryTodoRepository) Delete(id string) bool { for i, todo := range r.todos { if todo.ID == id { r.todos = append(r.todos[:i], r.todos[i+1:]...) return true } } return false }
2.4 Model(模型层)
package model type Todo struct { ID string `json:"id"` Title string `json:"title"` Done bool `json:"done"` }
三、运行结果
在终端中打开项目,运行项目
go run main.go
再打开一个新的终端
这里使用 Invoke-WebRequest 发送 POST 请求
$headers = @{ "Content-Type" = "application/json" } $body = @{ "title" = "Learn Fiber" "done" = $false } | ConvertTo-Json Invoke-WebRequest -Uri "http://localhost:3000/todos" -Method POST -Headers $headers -Body $body
解析:
Headers 字典创建:
$headers = @{ "Content-Type" = "application/json" }
Body 对象创建:
$body = @{ "title" = "Learn Fiber" "done" = $false } | ConvertTo-Json
发送 POST 请求:
curl -X POST http://localhost:3000/todos -H "Content-Type: application/json" -d '{"title": "Learn Fiber", "done": false}'
响应结果:
成功发送了 POST 请求
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!