当前位置: 首页 > article >正文

用 Go 和 Redis 构建一个简单的任务管理系统

用 Go 和 Redis 构建一个简单的任务管理系统

在这篇博客中,我们将使用 Go 语言结合 Gin 框架和 Redis,一步步创建一个简单的任务管理系统。本系统可用于执行关键的 CRUD(创建、读取、更新、删除)操作,我们特别关注如何通过 Redis 作为数据存储实现这些功能。

介绍

任务管理系统的特点在于能够让用户轻松地创建、查看和删除任务。现代的应用程序需要快速的数据写入和读取,而 Redis 提供了这样的能力,因此非常适合我们的需求。

项目初始化

1. 创建项目目录并初始化 Go 模块

首先,开始创建项目目录,并在我们的新目录中初始化 Go 模块:

mkdir task-manager
cd task-manager
go mod init task-manager

此操作将创建一个 go.mod 文件,用于管理我们的项目依赖。

安装依赖项

下面我们来安装必要的依赖库——Gin 用于处理 HTTP 请求,Go-Redis 用于连接和操作 Redis:

go get -u github.com/gin-gonic/gin
go get -u github.com/go-redis/redis/v8

这些库将为我们后续的开发提供强大的功能支持。

配置 Redis 连接

在项目根目录下创建 main.go 文件,用于初始化 Redis 连接和启动服务器:

package main

import (
    "task-manager/controllers"
    "github.com/gin-gonic/gin"
    "github.com/go-redis/redis/v8"
)

var rdb *redis.Client

func initRedis() {
    rdb = redis.NewClient(&redis.Options{
        Addr: "localhost:6379", // 设置 Redis 地址
    })
}

func main() {
    initRedis()

    r := gin.Default()

    // 设置路由
    r.POST("/tasks", controllers.CreateTask)
    r.GET("/tasks", controllers.GetTasks)
    r.DELETE("/tasks/:id", controllers.DeleteTask)

    r.Run(":8080")
}

代码解释

Redis 客户端初始化:我们使用 go-redis 客户端连接到本地 Redis 服务器。
Gin 路由设置:通过 Gin,我们将不同的 HTTP 路径绑定到相应的处理函数。

实现控制器逻辑

在项目的根目录下创建一个 controllers 目录,并创建 task.go 文件:

package controllers

import (
    "context"
    "net/http"
    "task-manager/models"
    "github.com/gin-gonic/gin"
    "strconv"
)

var ctx = context.Background()

func CreateTask(c *gin.Context) {
    var task models.Task
    if err := c.ShouldBindJSON(&task); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    task.ID = models.GenerateID()
    models.Rdb.Set(ctx, strconv.Itoa(task.ID), task.Title, 0)

    c.JSON(http.StatusOK, gin.H{"message": "Task created successfully", "id": task.ID})
}

func GetTasks(c *gin.Context) {
    keys, _ := models.Rdb.Keys(ctx, "*").Result()

    var tasks []models.Task
    for _, key := range keys {
        title, _ := models.Rdb.Get(ctx, key).Result()
        id, _ := strconv.Atoi(key)
        tasks = append(tasks, models.Task{ID: id, Title: title})
    }

    c.JSON(http.StatusOK, tasks)
}

func DeleteTask(c *gin.Context) {
    id := c.Param("id")
    models.Rdb.Del(ctx, id)

    c.JSON(http.StatusOK, gin.H{"message": "Task deleted successfully"})
}

代码解释

创建任务: 从请求中绑定任务数据后,在 Redis 中以键值对的形式存储。
获取所有任务: 遍历 Redis 中的所有键,获取并返回所有任务。
删除任务: 根据任务 ID 在 Redis 中删除相应的记录。

定义任务模型

models 目录下创建 task.go 文件来定义任务的数据模型:

package models

import (
    "github.com/go-redis/redis/v8"
)

type Task struct {
    ID    int    `json:"id"`
    Title string `json:"title" binding:"required"`
}

var Rdb *redis.Client

func SetRedisClient(client *redis.Client) {
    Rdb = client
}

func GenerateID() int {
    return int(Rdb.Incr(ctx, "task_id_counter").Val())
}

代码解释

Task 结构体:定义了任务的基本信息,包括 ID 和标题。
ID 生成: 使用 Redis 的自增功能自动为每个任务生成唯一 ID。

使用 Postman 进行测试

1. 创建任务 (POST /tasks)

步骤:

1.打开 Postman,创建一个新的请求。
2.设置请求方法为 POST,请求 URL 为 http://localhost:8080/tasks
3.在请求的 Body 部分,选择 rawJSON 格式。
4.输入任务数据,例如:

{
  "title": "Buy groceries"
}

点击 Send

期望响应:
服务器返回 200 OK,并带有任务创建成功的消息和新任务的 ID:

{
  "message": "Task created successfully",
  "id": 1
}

2. 获取任务列表 (GET /tasks)

步骤

1.在 Postman 中创建一个新的请求。
2.设置请求方法为 GET,请求 URL 为 http://localhost:8080/tasks
3.点击 Send

期望响应

服务器返回 200 OK,并返回所有任务的列表:

[
  {
    "id": 1,
    "title": "Buy groceries"
  }
  // 可以有更多任务
]

3. 删除任务 (DELETE /tasks/:id)

步骤:
1.在 Postman 中创建一个新的请求。
2.设置请求方法为 DELETE,将请求 URL 设置为 http://localhost:8080/tasks/1,其中 1 替换为您想要删除的任务的 ID。
3.点击 Send.

期望响应:
服务器返回 200 OK,并带有任务删除成功的消息:

{
  "message": "Task deleted successfully"
}

其他注意事项

数据格式:确保在发送请求时,Body 的 JSON 格式数据正确,避免请求因格式问题而失败。
错误处理:测试用例应包括错误处理,例如尝试获取或删除不存在的任务以查看系统的错误响应。
Redis 可视化工具:可以使用 Redis 可视化工具(如 RedisInsight)查看任务在 Redis 中的存储情况。

通过这些步骤,您可以用 Postman 充分验证任务管理系统的功能,并确保系统正确地处理数据。您还可以进一步扩展功能,例如添加更新任务的能力或用户身份验证机制,加强系统的实用性。


http://www.kler.cn/a/325966.html

相关文章:

  • sharding-jdbc自定义分片算法,表对应关系存储在mysql中,缓存到redis或者本地
  • VMware 中 虚拟机【Linux系统】固定 ip 访问
  • 解决Ubuntu18.04及以上版本高分辨率下导致字体过小问题
  • 前端:HTML (学习笔记)【1】
  • Cyberchef配合Wireshark提取并解析TCP/FTP流量数据包中的文件
  • MySQL技巧之跨服务器数据查询:基础篇-A数据库与B数据库查询合并--封装到存储过程中
  • 【MySQL】服务器管理与配置
  • FPGA学习(1)-mux2,2选1多路器
  • 速盾:网页游戏部署高防服务器有什么优势?
  • 数据结构编程实践20讲(Python版)—02链表
  • CAD图纸加密软件有哪些好用的?10款企业必备的图纸加密软件!
  • javdoc:(JDK9)VISITOR模式遍历语法树(DocCommentTree)获取代码注释中的tag(@return,@param)对象
  • 【Linux】基于驱动框架的程序编写测试
  • 全国糖酒会全域采购商选品会前瞻-见证零售新势力的崛起与变革
  • 第七讲-按钮控件QRadioButton
  • LINUX之Ansible自动化运维工具配置和ssh-keygen配置远程免密钥登录
  • InputStream为什么不能被重复读取?为啥只能被读取一次?
  • 探索 Android DataBinding:实现数据与视图的完美融合
  • 腾讯邮箱上传附件卡、慢、无法上传,下载慢问题处理
  • Harmony 获取定位位置的方式
  • 休眠唤醒不了?你的4G模组不是装睡,而是少了一条指令…
  • Spring Mvc 基础源码分析
  • OceanBase 关于一号表笔记与ERROR 1060(42S21)问题
  • 表驱法优化代码
  • 入职2年的程序员,被劝退了!年纪大了,感觉好绝望!
  • Studying-图论包含的算法总结