用Go语言标准库实现Web服务之项目介绍

 更新时间:2023年05月21日 10:15:06   作者:LightSaid  
从本节开始将从后端到前端一步一步实现一个Go语言Web服务,后端除了MySQL驱动,全部使用Go语言标准库来实现一个小型项目,本篇将简单的介绍一下项目开发要准备的流程,感兴趣的同学可以阅读一下

我们将要创建一个什么项目呢?

我们要创建的项目是一个EBook电子书平台,接受用户注册登录浏览图书,用户可以购买图书,系统自动将电子书(pdf、epub 等格式电子书)发送到用户邮箱。这就是整个系统主线任务。

当然整个项目不是一蹴而就马上编写完成,而是分阶段实现,每个阶段都有不同技术栈,像一个真实项目一样迭代开发。

用户可以浏览平台所有电子书,管理员可以对图书进行CRUD操作。

在第一阶段,我将使用Go语言标准库实现单表CRUD API 接口。

在这一个阶段先创建一个电子书表book,使用 MySQL 5.7版本 先维护好book表的功能,继而迭代开发;建库建表 SQL 语句如下:

CREATE DATABASE db_ebook; 
USE db_ebook;

CREATE TABLE book (
    id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT '主键',
    isbn VARCHAR(13) NOT NULL COMMENT '国际标准书号',
    title VARCHAR(255) NOT NULL COMMENT '图书名字',
    poster  VARCHAR(255) NOT NULL COMMENT '图书封面图地址',
    pages INT UNSIGNED NOT NULL COMMENT '总页数',
    price DECIMAL(6, 2) UNSIGNED COMMENT '图书单价',
    published_at DATE NOT NULL COMMENT '发售日期',
    created_at TIMESTAMP NOT NULL default NOW() COMMENT '创建时间',
    updated_at TIMESTAMP NOT NULL default NOW() COMMENT '更新时间',
    unique index unq_isbn(`isbn`)
) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT '图书表';

项目目录结构组织

在这一步,我将设计一个简洁实用的代码组织架构,符合Go语言哲学思想,所见即所得。

初始化项目,使用 Go Module 开发;

mkdir -p $GOPATH/src/github.com/lightsaid/ebook
cd $GOPATH/src/github.com/lightsaid/ebook
go mod init github.com/lightsaid/ebook
code .

目录结构

        ├── configs         配置文件,可以有多个,例如开发/生产环境配置
        │   └── app.json    
        ├── go.mod         
        ├── go.sum
        ├── internal       系统内部逻辑在此处实现
        │   ├── app        app 要实现的api应用程序
        │   ├── config     加载配置
        │   ├── dbrepo     数据库操作
        │   └── models     实体模型
        ├── main.go        入口函数
        ├── pkg            公共模块,可以提供给其他项目使用的模块
        │   └── logger     日志库
        └── schema.sql

在Go中,internal 目录是本项目内部代码,不提供给其他项目使用,而且不管internal嵌套在一级、二级、三级...都是同样不允许外部项目访问;Go在编译的时候做了区分。如果你想详细了解Go如何组织代码可以参考这个项目 project-layout

在上面其中pkg目录是存放公共模块代码,如核心业务没有太多联系辅助模块,它可以提供给其他项目使用,尽管其他项目也不会用到😂。

在这一阶段,先来热身一下,先编写简单的 logger 日志输出功能和加载配置功能。 好在这一部分先介绍到这么多,下一节将开始编码。

logger/logger.go

package logger
import (
    "log"
    "os"
)
var InfoLog *log.Logger
var ErrorfoLog *log.Logger
func SetGlobalLogger() {
    InfoLog = log.New(os.Stdout, "[INFO]\t", log.Ldate|log.Ltime)
    ErrorfoLog = log.New(os.Stdout, "[ERROR]\t", log.Ldate|log.Ltime|log.Lshortfile)
}

上面创建两个log实例,并配置日志输出前缀,和日期文件名等信息

app.json (端口根据自己实际配置)

{
    "env": "dev",
    "port": 9527,
    "dsn": "root:rootcc@tcp(127.0.0.1:3318)/db_ebook?charset=utf8mb4&parseTime=True",
    "maxOpenConns": 30,
    "maxIdleConns": 15,
    "maxIdleTime": "5m"
}

config/config.go

package config

import (
	"encoding/json"
	"fmt"
	"os"
	"time"

	"github.com/lightsaid/ebook/pkg/logger"
)

// AppConfig 应用程序配置
type AppConfig struct {
	Env          string `json:"env"`          // 环境参数:dev | prod
	Port         int    `json:"port"`         // 服务端口
	DSN          string `json:"dsn"`          // 数据库链接
	MaxOpenConns int    `json:"maxOpenConns"` // 数据库最大链接数
	MaxIdleConns int    `json:"maxIdleConns"` // 数据库链接最大空闲数
	MaxIdleTime  string `json:"maxIdleTime"`  // 数据库链接最大空闲时间
}

// MaxIdleTimeToDuration 将 MaxIdleTime 转换成 time.Duration 返回,如果转换出错,返回默认值
func (app *AppConfig) MaxIdleTimeToDuration() time.Duration {
	dur, err := time.ParseDuration(app.MaxIdleTime)
	if err != nil {
		logger.ErrorfoLog.Println("time.ParseDuration(app.MaxIdleTime) failed: " + err.Error())
		return time.Minute * 5
	}
	return dur
}

// LoadAppConfig 根据配置文件路径加载配置
func LoadAppConfig(path string) (cfg AppConfig, err error) {
	var buf []byte
	buf, err = os.ReadFile(path)
	if err != nil {
		return
	}
	if err = json.Unmarshal(buf, &cfg); err != nil {
		return
	}

	return
}

func (a *AppConfig) Println() {
	if a.Env == "dev" {
		buf, _ := json.MarshalIndent(a, "", " ")
		fmt.Println(string(buf))
	}
}

在上面创建一个AppConfig结构体,并绑定json tag,这样json.Unmarshal才能解码。 在 Println 方法中 json.MarshalIndent 是格式化输出json函数。上面格式输出如图:

这部分内容分享到这里,下一节将初始化App路由。

到此这篇关于用Go语言标准库实现Web服务之项目介绍的文章就介绍到这了,更多相关Go语言标准库 实现Web服务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • golang channel读取数据的几种情况

    golang channel读取数据的几种情况

    本文主要介绍了golang channel读取数据的几种情况,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • gin通过go build -tags实现json包切换及库分析

    gin通过go build -tags实现json包切换及库分析

    这篇文章主要为大家介绍了gin通过go build -tags实现json包切换及库分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 如何使用 Go 和 Excelize 构建电子表格

    如何使用 Go 和 Excelize 构建电子表格

    这篇文章主要介绍了如何使用Go和Excelize构建电子表格,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • Go语言基础go install命令使用示例详解

    Go语言基础go install命令使用示例详解

    这篇文章主要为大家介绍了Go语言基础go install命令的使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2021-11-11
  • Go语言函数学习教程

    Go语言函数学习教程

    这篇文章主要介绍了Go语言函数基本用法,结合实例形式分析了Go语言函数的格式、定义、使用方法与相关注意事项,需要的朋友可以参考下
    2016-07-07
  • Go依赖注入工具wire的具体使用

    Go依赖注入工具wire的具体使用

    本文主要介绍了Go依赖注入工具wire的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • 浅谈golang 中time.After释放的问题

    浅谈golang 中time.After释放的问题

    这篇文章主要介绍了浅谈golang 中time.After释放的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • Go中数组传参的几种方式小结

    Go中数组传参的几种方式小结

    本文主要介绍了Go中数组传参的几种方式小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Go语言开发技巧必知的小细节提升效率

    Go语言开发技巧必知的小细节提升效率

    这篇文章主要介绍了Go语言开发技巧必知的小细节提升效率,分享几个你可能不知道的Go语言小细节,希望能帮助大家更好地学习这门语言
    2024-01-01
  • 举例讲解Go语言中函数的闭包使用

    举例讲解Go语言中函数的闭包使用

    这篇文章主要介绍了Go语言中函数的闭包使用示例,函数闭包closure是编程语言中十分重要的特性,需要的朋友可以参考下
    2016-03-03

最新评论