vblog01

command module
v0.0.0-...-12c2583 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2024 License: Apache-2.0 Imports: 2 Imported by: 0

README

微博客

前端后端分离的博客系统, 是一个单体应用

产品

用户定位:

  • 访客: 浏览博客的人
  • 作者: 写博客的人

产品的原型

架构

技术架构

业务逻辑代码组织方式

首先使用go mod init 初始化一个Go项目工程, vscode 打开这个工程(在这个工程下面由go.mod文件)

业务代码组织风格:

  • MVC 分层架构: 比较传统的代码组织风格
  • 微服务渐进架构: 微服务的孵化,业务开展之前, 尽量少的划分服务(2 ~5个服务)
  • DDD 分区架构(Domain Driven Develop): 域(领域): 一个业务单元(商品管理/订单管理), 理解为一个业务分区

基于DDD和TDD的功能分区架构: Blog业务实现流程

代码开发的2种方式:

  • 从上往下 进行设计, 顶层设计
  • 从下往上 做业务的具体实现 (推荐)

RESTful接口设计

// 文章管理 API, 同时设计业务接口(需要暴露成HTTP RESTFUL) 业务接口定义

HTTP 接口 只是把业务接口的能通过HTTP协议对外进行暴露

// POST // action: /vblog/api/v1/blogs/list // action: /vblog/api/v1/blogs/get? // action: /vblog/api/v1/blogs/create? // Jquery

GET /vblog/api/v1/blogs 获取博客列表

POST /vblog/api/v1/blogs 创建博客 参数通过Body

GET /vblog/api/v1/blogs/:id 获取单个文章

PUT /vblog/api/v1/blogs/:id 获取单个文章

DELETE /vblog/api/v1/blogs/:id 删除单个文章

数据库的设计

文章: Blog

文章的元数据:

  • 文章的Id
  • 创建时间
  • 修改时间

用户传入的数据

  • 标题
  • 作者
  • 发布时间
  • 内容(Markdown)
  • 标签(map)

补充数据库的建库,建表

准备一个MySQL数据库: 使用docker安装一个mysql

docker run mysql

项目开发

项目骨架做定义(流程是从下到上的)

  • 业务处理模块: 每个业务一个模块: apps

  • 项目的配置管理: pkg conf 项目的运行参数, 通过配置传递给程序: conf

  • 项目的文档: docs

  • 项目的接口: protocol 协议服务器, 监听对应的端口(http server/grpc server), 处理用户的连接

  • 项目CLI: cmd 项目的cli工具(cobra), ./vblog start/init

  • 项目入口文件: main.go, 项目所有的包,类, 在main.go 进行程序组装

  • 程序日志处理: logurs/zap/zerolog, 项目里面我们使用zerolog, 程序里面负责统一打印日志的组件: logger

  • 程序的配置文件: 加载配置文件目录

    • 文件格式的配置: config.toml
    • 环境变量的配置: config.env
    • 程序的样例配置: config.example.toml
    • 单元测试配置: unit_test.env(vscode 使用的)
  • .gitignore: 哪些文件忽略不提交, config.toml

v1.0版本 问题

业务开发流程:

  • 写业务模块, 业务模块并没有被加载到框架中去
  • 加载业务逻辑, 收到添加业务逻辑的初始化
		// 加载业务逻辑实现
		r := gin.Default()

		// blog 业务模块
		blogService := &impl.Impl{}
		err := blogService.Init()
		cobra.CheckErr(err)
		apiHandler := api.NewHandler(blogService)
		apiHandler.Registry(r)

    // 20多个业务模块
    ...
    ...
  1. 注意里面不能集中在写业务功能上, 不希望在apps模块之外还要做业务代码的添加
  2. 对象的依赖问题, 一些其他的负责的业务, 可能会已很多业务对象来开发上层业务

v2.0版本

核心采用Ioc来进行重构

实现ioc

    1. 先写业务实现
    1. 再写接口实现
    1. 实例注册到ioc
    1. 程序启动的时候, 注册所有的实例: apps/registry.go,

注册业务对象

import (
	// 注册api handler
	_ "gitee.com/go-course/go11/vblog/apps/blog/api"

	// 注册 blog 业务具体实现
	_ "gitee.com/go-course/go11/vblog/apps/blog/impl"
)

接口测试

请求 POST

curl --location 'http://127.0.0.1:8010/vblog/api/v1/blogs' \
--header 'Authorization: bearer xFonlTKhEtFqnUvhGiGv5fiL' \
--header 'Content-Type: application/json' \
--data '{
    "title": "api test",
    "author": "oldyu",
    "content": "go项目教学"
}'

请求的返回

{
    "id": 23,
    "created_at": 1685168742,
    "updated_at": 1685168742,
    "pulished_at": 0,
    "title": "api test",
    "author": "oldyu",
    "content": "go项目教学",
    "tags": {},
    "status": 0
}

如果控制枚举类型的序列化: "status": 0

  • "status": "草稿/Draft", 0 ---> 草稿

objcect(内存中的数据结构) --> json(字符串), 对于枚举类型,我们我们来控制如何暂时, 如何自定义JSON序列化

// Marshaler is the interface implemented by types that
// // can marshal themselves into valid JSON.
// type Marshaler interface {
// 	MarshalJSON() ([]byte, error)
// }
// 你自己定义当前类型的JSON输出, 一定要是一个合法的JSON
// "status": "xxx", "xxx"
func (s STATUS) MarshalJSON() ([]byte, error) {
	switch s {
	case STATUS_DRAFT:
		// 草稿   "草稿"
		return []byte(`"草稿"`), nil
	case STATUS_PUBLISHED:
		return []byte(`"已发布"`), nil
	}

	return []byte(fmt.Sprintf("%d", s)), nil
}

GET: 查询文章列表

curl --location 'http://127.0.0.1:8010/vblog/api/v1/blogs?keywords=%E9%A1%B9%E7%9B%AE%E6%95%99%E5%AD%A6' \
--header 'Authorization: bearer xFonlTKhEtFqnUvhGiGv5fiL'
{
    "total": 1,
    "items": [
        {
            "id": 23,
            "created_at": 1685168742,
            "updated_at": 1685168742,
            "pulished_at": 0,
            "title": "api test",
            "author": "oldyu",
            "content": "go项目教学",
            "tags": {},
            "status": "草稿"
        }
    ]
}

认证功能开发

验证认证接口:

curl --location 'http://localhost:8010/vblog/api/v1/tokens' \
--header 'Authorization: bearer xFonlTKhEtFqnUvhGiGv5fiL' \
--header 'Content-Type: application/json' \
--header 'Cookie: token=chotfbp3n7pgk12r9iog' \
--data '{
    "username": "admin",
    "passwrod": "123456"
}'

程序的Debug

  1. 单元测试: 调试某个函数
  2. 程序Debug: 程序以Debug启动

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
client
cmd

Jump to

Keyboard shortcuts

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