go实践之apiserver搭建
go实践之apiserver搭建
本文主要记录下博主用gin搭建app server的过程,方便后续学习。web框架用的gin,日志用的zap,数据库连接用的mysql driver,配置文件读取用的是viper。整个项目的框架如下:
.
├── app
│ ├── comment.go
│ ├── server.go
│ └── user.go
├── config.toml
├── Gopkg.lock
├── Gopkg.toml
├── LICENSE
├── main.go
├── README.md
├── tool
│ ├── config
│ │ ├── config.go
│ │ └── config_test.go
│ ├── db
│ │ ├── mysql.go
│ │ └── mysql_test.go
│ └── log
│ ├── log.go
│ └── log_test.go
└── vendor
├── github.com
......
main.go作为整个api server 的入口文件,tool文件夹下面存放了日志,数据库,配置文件相关代码。app文件夹里面是api实现相关的代码。
1、配置文件读取
配置文件读取的代码如下:
package config
import(
"fmt"
"github.com/spf13/viper"
)
func ParseConfig() error {
viper.SetConfigName("config") // name of config file (without extension)
viper.AddConfigPath("./conf") // call multiple times to add many search paths
viper.AddConfigPath(".") // optionally look for config in the working directory
err := viper.ReadInConfig() // Find and read the config file
if err != nil { // Handle errors reading the config file
return fmt.Errorf("Fatal error config file: %s \n", err)
}
viper.WatchConfig()
return nil
}
这里只是简单的一个demo,viper还有更多的功能,比如设置默认值 viper.SetDefault("ContentDir", "content")
,可以加载环境变量中的值AutomaticEnv()
,热更新配置文件 viper.WatchConfig()
。具体可以参考官方文档:链接。
2、数据连接
本文件主要实现的是数据库连接,以及增删查改操作。具体代码如下:
package db
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"time"
"github.com/spf13/viper"
"fmt"
)
type DbConn struct {
Db *sql.DB
}
func InitDbConn()(*DbConn, error) {
dbConn := viper.GetString("Database.DbConn")
db, err := sql.Open("mysql", dbConn)
if err != nil {
return nil, fmt.Errorf("get db connection error")
}
maxOpenConns := viper.GetInt("Database.MaxOpenConn") //从配置文件中获取配置值
maxIdleConns := viper.GetInt("Database.MaxIdleConn")
maxLifetime := viper.GetInt("Database.MaxLifetime")
......//省略部分代码
err = db.Ping()
if err != nil {
return nil,fmt.Errorf("connect to db error")
}else{
dbconn := &DbConn{Db:db}
return dbconn,nil
}
}
func (c *DbConn) Insert(sql string, args ...interface{}) (lastInsertId int64, err error) {
res, err := c.Db.Exec(sql, args...)
if err != nil {
return
}
return res.LastInsertId()
}
......//省略部分代码
主要是调用mysql driver根据配置文件配置值连接数据库。
3、日志初始化
日志主要的是uber的zap日志框架,这是一个高性能的日志框架,在这里有点小用它了。也只是一个简单的使用举例。更多功能需要去学习。
package log
import (
"fmt"
"strings"
"github.com/spf13/viper"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
var Logger *zap.SugaredLogger //global logger
func InitLog() {
logLevel := viper.GetString("Log.LogLevel")
logName := viper.GetString("Log.LogName")
logAge := viper.GetInt("Log.LogAge")
logSize := viper.GetInt("Log.LogSize")
w := zapcore.AddSync(&lumberjack.Logger{
Filename: logName,
MaxSize: logSize, // megabytes
MaxBackups: 3,
LocalTime: true,
MaxAge: logAge, // days
})
zapLogLevel := zap.NewAtomicLevel()
if err := zapLogLevel.UnmarshalText([]byte(strings.ToLower(logLevel))); err != nil {
panic(fmt.Errorf("get config log level:%v config error: %v", logLevel, err))
}
.....//此处省略部分代码
logger := zap.New(core, zap.AddCaller())
Logger = logger.Sugar()
Logger.Info("logger init successful!")
}
4、server初始化
主要就是调用配置读取函数,数据库连接和日志初始化函数,再启动http server
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"github.com/zhanben/go_site/app"
"github.com/zhanben/go_site/tool/config"
"github.com/zhanben/go_site/tool/db"
"github.com/zhanben/go_site/tool/log"
"go.uber.org/zap"
)
func main() {
//Read config file
err := config.ParseConfig()
if err != nil {
panic(fmt.Errorf("Failed to read config file: %s \n", err))
}
//Init log
log.InitLog()
//Init db connection
db, err := db.InitDbConn()
if err != nil {
panic("connect db error!")
}
log.Logger.Info("Db init successful!")
//start http sever
startServer(db)
}
.....//此处省略部分代码
5、接口编写
下面是简单的两个接口实现的例子:一个是URL中带有参数,一个没有带的。
package app
import (
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"net/http"
"github.com/zhanben/go_site/tool/db"
)
.....//此处省略部分代码
func (u *User) initRouter(r *gin.RouterGroup) {
//在此添加接口
r.GET("/users", u.getAllUsers) //获取所有用户信息
r.GET("/users/:name", u.getOneUser) //根据用户名获取用户详细信息
}
func (u *User) getAllUsers(c *gin.Context) {
//构建返回结构体
res := map[string]interface{}{
"Action": "GetAllUserResponse",
"RetCode": 0,
}
sql := "select * from user limit 10"
result, err := u.db.Select(sql)
if err != nil {
u.Logger.Error("get user info from db error!")
abortWithError(u.Logger, c, err)
}
res["UserInfo"] = result
c.JSON(http.StatusOK, res)
}
func (u *User) getOneUser(c *gin.Context) {
//构建返回结构体
res := map[string]interface{}{
"Action": "GetOneUserResponse",
"RetCode": 0,
}
userName, ok :=c.Params.Get("name")
if !ok {
u.Logger.Error("parameter name must be fixed!")
}
u.Logger.Infof("get user name from url:%s",userName)
sql := "select * from user where username=?"
result, err := u.db.Select(sql,userName)
if err != nil {
u.Logger.Error("get user info from db error!")
res["RetCode"]= "-1"
res["Error"] = "user not exist!"
}else{
res["UserInfo"] = result
u.Logger.Info("get one user info successful!")
}
c.JSON(http.StatusOK, res)
}
至此一个简单的go api sever的框架就搭建好了。当然后续还有单元测试的代码需要补充。本文的全部的代码可以到github下载:git clone --branch v0.1 git@github.com:Zhanben/go_site.git
go实践之apiserver搭建的更多相关文章
- 从零开始针对 .NET 应用的 DevOps 运营实践 - 运行环境搭建
一.Overview 最近的一段时间,在公司里我都在进行基于 Jenkins 和 SonarQube 配合已有的 Gitlab 搭建部门的持续集成环境的工作,虽然之前有使用过 GitHub Actio ...
- 前端项目模块化的实践1:搭建 NPM 私有仓库管理源码及依赖
以下是关于前端项目模块化的实践,包含以下内容: 搭建 NPM 私有仓库管理源码及依赖: 使用 Webpack 打包基础设施代码: 使用 TypeScript 编写可靠类库 使用 TypeScript ...
- 【机器学习PAI实践一】搭建心脏病预测案例
一.背景 心脏病是人类健康的头号杀手.全世界1/3的人口死亡是因心脏病引起的,而我国,每年有几十万人死于心脏病. 所以,如果可以通过提取人体相关的体侧指标,通过数据挖掘的方式来分析不同特征对于心脏病的 ...
- OceanBase数据库实践入门——手动搭建OceanBase集群
前言 目前有关OceanBase功能.案例.故事的文章已经很多,对OceanBase感兴趣的朋友都想安装一个数据库试试.本文就是分享初学者如何手动搭建一个OceanBase集群.这也是学习理解Ocea ...
- 运维开发实践——基于Sentry搭建错误日志监控系统
错误日志监控也可称为业务逻辑监控, 旨在对业务系统运行过程中产生的错误日志进行收集归纳和监控告警.似乎有那么点曾相识?没错... 就是提到的“APM应用性能监控”.但它又与APM不同,APM系统主要注 ...
- django入门与实践 3-1 环境搭建
Python 2.7 .Django对2.7.3.5.3.4都是支持的. https://www.djangoproject.com/download/ django对python的兼容情况 pip安 ...
- 2. react 编程实践 俄罗斯方块-环境搭建
1. 创建 demo 目录 mkdir demo 2. 初始化应用 npm init 工程信息 package name : tetris-class-demo version: descriptio ...
- go实践之swagger自动生成api文档
文章目录 go实践之swagger自动生成api文档 1.安装需要用到的包 2.接口代码支持swagger 3. 生成swagger接口 go实践之swagger自动生成api文档 作为一个后端开发, ...
- MySQL5.6 GTID新特性实践
MySQL5.6 GTID新特性实践 GTID简介 搭建 实验一:如果slave所需要事务对应的GTID在master上已经被purge了 实验二:忽略purged的部分,强行同步 本文将简单介绍基于 ...
随机推荐
- linux搭建简易网站
1.检查环境 getenforce #查看seLinux运行状态 Enforcing #强行执行 setenforce #临时关闭selinux vim /etc/selinux/config #编辑 ...
- Java设计模式之模板方法模式(Template)
前言: 我们在开发中有很多固定的流程,这些流程有很多步凑是固定的,比如JDBC中获取连接,关闭连接这些流程是固定不变的,变动的只有设置参数,解析结果集这些是根据不同的实体对象“来做调整”,针对这种拥有 ...
- tomcat的catalina.out日志切割
目前我们的日志文件catalina.out累积后非常大,部分应用的catalina.out达到几十G并且还在持续增长. 日志文件太大不便于阅读和排查问题.业务增长不断增长,日志也在不断增加,为了以后便 ...
- 【Spring】Spring的定时任务注解@Scheduled原来如此简单
1 简介 定时任务的实现非常多,JDK的Timer.Spring提供的轻量级的Scheduled Task.QuartZ和Linux Cron等,还有一些分布式的任务调度框架.本文主要介绍Schedu ...
- Feign 调用丢失Header的解决方案
问题 在 Spring Cloud 中 微服务之间的调用会用到Feign,但是在默认情况下,Feign 调用远程服务存在Header请求头丢失问题. 解决方案 首先需要写一个 Feign请求拦截器,通 ...
- 微擎 manifest.xml
微擎 manifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns= ...
- 检测当前IE浏览器的版本
检测当前IE浏览器的版本(注意:在非IE浏览器中是看不到效果的) 使用示例如下:低于IE8弹窗提示 <!--[if lte IE 8]><script>alert('您当前浏览 ...
- 2019-9-11:渗透测试,基础学习,VMware安装centos 7
VMware Workstation 15 Pro 安装Centos 7,详细图文步骤 1,点击VMware菜单栏的“文件”-->“新建虚拟机”,选择“典型”使用向导创建虚拟机,点击“下一步” ...
- 【Luogu P1502】窗口的星星
Luogu P1502 题意很好理解,就是问给出的矩形套住的最大和. 但是做起来却十分麻烦. --来自疯狂爆10分的愤怒 一个比较高效的思路是--把每一个星星作为左下角向右上方拓展形成一个矩形, 拓展 ...
- EntityFramework Core 3.0查询
前言 随着.NET Core 3.0的发布,EF Core 3.0也随之正式发布,关于这一块最近一段时间也没太多去关注,陆续会去对比之前版本有什么变化没有,本节我们来看下两个查询. 分组 我们知道在E ...