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搭建的更多相关文章

  1. 从零开始针对 .NET 应用的 DevOps 运营实践 - 运行环境搭建

    一.Overview 最近的一段时间,在公司里我都在进行基于 Jenkins 和 SonarQube 配合已有的 Gitlab 搭建部门的持续集成环境的工作,虽然之前有使用过 GitHub Actio ...

  2. 前端项目模块化的实践1:搭建 NPM 私有仓库管理源码及依赖

    以下是关于前端项目模块化的实践,包含以下内容: 搭建 NPM 私有仓库管理源码及依赖: 使用 Webpack 打包基础设施代码: 使用 TypeScript 编写可靠类库 使用 TypeScript ...

  3. 【机器学习PAI实践一】搭建心脏病预测案例

    一.背景 心脏病是人类健康的头号杀手.全世界1/3的人口死亡是因心脏病引起的,而我国,每年有几十万人死于心脏病. 所以,如果可以通过提取人体相关的体侧指标,通过数据挖掘的方式来分析不同特征对于心脏病的 ...

  4. OceanBase数据库实践入门——手动搭建OceanBase集群

    前言 目前有关OceanBase功能.案例.故事的文章已经很多,对OceanBase感兴趣的朋友都想安装一个数据库试试.本文就是分享初学者如何手动搭建一个OceanBase集群.这也是学习理解Ocea ...

  5. 运维开发实践——基于Sentry搭建错误日志监控系统

    错误日志监控也可称为业务逻辑监控, 旨在对业务系统运行过程中产生的错误日志进行收集归纳和监控告警.似乎有那么点曾相识?没错... 就是提到的“APM应用性能监控”.但它又与APM不同,APM系统主要注 ...

  6. django入门与实践 3-1 环境搭建

    Python 2.7 .Django对2.7.3.5.3.4都是支持的. https://www.djangoproject.com/download/ django对python的兼容情况 pip安 ...

  7. 2. react 编程实践 俄罗斯方块-环境搭建

    1. 创建 demo 目录 mkdir demo 2. 初始化应用 npm init 工程信息 package name : tetris-class-demo version: descriptio ...

  8. go实践之swagger自动生成api文档

    文章目录 go实践之swagger自动生成api文档 1.安装需要用到的包 2.接口代码支持swagger 3. 生成swagger接口 go实践之swagger自动生成api文档 作为一个后端开发, ...

  9. MySQL5.6 GTID新特性实践

    MySQL5.6 GTID新特性实践 GTID简介 搭建 实验一:如果slave所需要事务对应的GTID在master上已经被purge了 实验二:忽略purged的部分,强行同步 本文将简单介绍基于 ...

随机推荐

  1. .NET手撸绘制TypeScript类图——上篇

    .NET手撸绘制TypeScript类图--上篇 近年来随着交互界面的精细化,TypeScript越来越流行,前端的设计也越来复杂,而类图正是用简单的箭头和方块,反映对象与对象之间关系/依赖的好方式. ...

  2. [UWP]使用CompositionAPI的翻转动画

    1. 运行效果 在 使用GetAlphaMask和ContainerVisual制作长阴影(Long Shadow) 这篇文章里我介绍了一个包含长阴影的番茄钟,这个番茄钟在状态切换时用到了翻转动画,效 ...

  3. show语句大全

    基于本人对MySQL的使用,现将常用的MySQL show 语句列举如下: 1.show databases ; // 显示mysql中所有数据库的名称 2.show tables [from dat ...

  4. thinkphp分页样式css代码

    <style type="text/css"> .Pagination a:hover,.current{background-color: #f54281;borde ...

  5. 理解Spark运行模式(二)(Yarn Cluster)

    上一篇说到Spark的yarn client运行模式,它与yarn cluster模式的主要区别就是前者Driver是运行在客户端,后者Driver是运行在yarn集群中.yarn client模式一 ...

  6. .NET core3.0 使用Jwt保护api

    摘要: 本文演示如何向有效用户提供jwt,以及如何在webapi中使用该token通过JwtBearerMiddleware中间件对用户进行身份认证. 认证和授权区别? 首先我们要弄清楚认证(Auth ...

  7. 20191010-5 alpha week 1/2 Scrum立会报告+燃尽图 03

    此作业要求参见[https://edu.cnblogs.com/campus/nenu/2019fall/homework/8748] 一.小组情况 队名:扛把子 组长:迟俊文 组员:宋晓丽 梁梦瑶 ...

  8. java基础总结(1)--深入理解基本数据类型

    深入理解java数据类型 java是一种强类型语言,这就意味着必须为每一个声明变量声明一种类型.在java中,一共有8种数据类型,其中4种整型,2种浮点类型,1种字符类型和一种表示真值的boolean ...

  9. [折腾笔记] 洛谷P1149-火柴棒等式 AC记

    原题链接: https://www.luogu.org/problem/P1149 题面简述: 给你n根火柴棍,你可以拼出多少个形如"A+B=C""A+B=C" ...

  10. 【浅析】|白话布隆过滤器BloomFilter

    通过本文将了解到以下内容: 查找问题的一般思路 布隆过滤器的基本原理 布隆过滤器的典型应用 布隆过滤器的工程实现 场景说明: 本文阐述的场景均为普通单机服务器.并非分布式大数据平台,因为在大数据平台下 ...