0x0 Gin简介

1.Gin 是什么?

Gin 是一个用 Go (Golang) 编写的 HTTP web 框架。 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httprouter,速度提高了近 40 倍。如果你需要极好的性能,使用 Gin 吧。

2.Gin相关地址

doc:https://gin-gonic.com/zh-cn/docs/

github:https://github.com/gin-gonic/gin

0x1 快速开始

1. 用module模式创建工程

mkdir web_api

cd web_api

go mod init web_api

2.创建main.go

import "github.com/gin-gonic/gin"

func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}

3. 运行

go run main.go

4. 浏览器打开 127.0.0.1:8080/ping

0x2 实践

1. 说明

1)这是一个简单的例子,实现了通过id查找数据库获取用户名字的功能。

2)使用了MVC结构,当然也可以不套用这种结构。好处就是开发web程序结构会清晰很多。

3)使用了go modules的包管理方式确实方便很多。不清楚的可以看我另外一篇关于go modules的介绍https://www.cnblogs.com/mrblue/p/11277100.html

4)依赖了yml和gorm库

2.目录结构如下

│ config.yml
│ go.mod
│ go.sum
│ main.go
│ Makefile
│ README.md
├─app
│    app.go
│    handle.go
│    routers.go

├─controllers
│    user.go

├─models
│   model.go
│   user.go

├─routers
│   router.go

└─service
    user.go

3.主要文件说明

1)app/app.go 应用程序文件,负责初始化gin上下文,处理信号量

package app

import (
"context"
"log"
"net/http"
"os"
"os/signal"
"time"
"web_api/routers"
"github.com/gin-gonic/gin"
) type Config struct {
Port string
Debug bool
} func Run(cfg Config) {
router := gin.Default()
routes.RegisterRouters(router)
srv := &http.Server{
Addr: ":" + cfg.Port,
Handler: router,
} go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}() quit := make(chan os.Signal)
signal.Notify(quit, os.Interrupt)
<-quit
log.Println("Shutdown Server ...") ctx, cancel := context.WithTimeout(context.Background(), *time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
}

2) controllers/user.go 控制文件,获取请求参数,调用service的逻辑方法,然后返回结果

package controllers

import (
"net/http" "web_api/service" "github.com/gin-gonic/gin"
) func GetName(c *gin.Context) { id := c.Param("id")
r := service.User{ID: id}
name, err := r.GetName()
if nil != err {
c.String(http.StatusInternalServerError, err.Error())
return
} c.JSON(http.StatusOK, gin.H{"error": "ok", "name": name})
}

3) models/model.go 数据库的初始化

package models

import (
"fmt" "github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
) // Config 配置
type Config struct {
User string
Password string
Host string
Name string
} var (
db *gorm.DB
) // Setup initializes the database instance
func Setup(cfg Config) error { var err error
db, err = gorm.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
cfg.User,
cfg.Password,
cfg.Host,
cfg.Name)) if err != nil {
return err
} db.SingularTable(true)
db.DB().SetMaxIdleConns()
db.DB().SetMaxOpenConns()
return nil
} // CloseDB closes database connection (unnecessary)
func CloseDB() {
defer db.Close()
}

4) models/user.go user数据库表的增删改查

package models

import (
"github.com/jinzhu/gorm"
) type User struct {
ID string `gorm:"primary_key;type:INT(20)"`
Age int32 `gorm:"type:INT(20)"`
Name string `gorm:"type:VARCHAR(256)"`
Desc string `gorm:"type:VARCHAR(256)"`
}

  func (User) TableName() string {
    return "user"
  }

func GetUser(id string) (*User, error) {
u := &User{
ID: id,
}
err := db.First(u).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
} return u, nil
}

5) routers/router.go 定义路由

package routers

import (
"web_api/controllers" "github.com/gin-gonic/gin"
) // RegisterRouters ...
func RegisterRouters(g *gin.Engine) {
g.GET("/name/:id", controllers.GetName)
}

6) service/user.go user的逻辑

package service

import (
"web_api/models"
) type User struct {
ID string
} func (r *User) GetName() (string, error) {
u, err := models.GetUser(r.ID)
if nil != err {
return "", err
}
return u.Name, nil
}

7) main.go

package main

import (
"flag"
"io/ioutil"
"log" "web_api/app"
"web_api/models" "gopkg.in/yaml.v2"
) // Config 配置
type Config struct {
App app.Config
Model models.Config
} var (
cfgPath = flag.String("config", "config.yml", "config file path")
) func main() {
cfg := Config{}
if data, err := ioutil.ReadFile(*cfgPath); nil != err {
panic(err)
} else {
if err := yaml.Unmarshal(data, &cfg); nil != err {
panic(err)
}
} if err := models.Setup(cfg.Model); nil != err {
panic(err)
} app.Run(cfg.App) log.Println("Server exiting")
}

4.配置文件 confg.yml

app:
port:
debug: true model:
user: root
password: xxxxx
host: 127.0.0.1:
name: mydb

5.测试

1)需要你的mysql有个叫mydb的库,里有一张叫user的表

2)查找id魏1000的人的名字,浏览器打开 http://127.0.0.1:8080/name/1000

[Golang] Gin框架学习笔记的更多相关文章

  1. 前端程序员学习 Golang gin 框架实战笔记之一开始玩 gin

    原文链接 我是一名五六年经验的前端程序员,现在准备学习一下 Golang 的后端框架 gin. 以下是我的学习实战经验,记录下来,供大家参考. https://github.com/gin-gonic ...

  2. Golang gin框架学习

    今天开始学习gin框架,在Github上找的示例的go-gin-example, 进度 日期 进展 疑惑 进展 1.30 下拉代码,初步了解gin的介绍.搭建 .mod文件 module原理.使用方法 ...

  3. kratos微服务框架学习笔记一(kratos-demo)

    目录 kratos微服务框架学习笔记一(kratos-demo) kratos本体 demo kratos微服务框架学习笔记一(kratos-demo) 今年大部分时间飘过去了,没怎么更博和githu ...

  4. golang(gin框架),基于RESTFUL的跨语言远程通信尝试

    golang(gin框架),基于RESTFUL的跨语言远程通信尝试 背景: 在今年的项目实训过程中,遇到了这样的问题: 企业老师讲课实用的技术栈是Java springboot. 实训实际给我们讲课以 ...

  5. phalcon(费尔康)框架学习笔记

    phalcon(费尔康)框架学习笔记 http://www.qixing318.com/article/phalcon-framework-to-study-notes.html 目录结构   pha ...

  6. Yii框架学习笔记(二)将html前端模板整合到框架中

    选择Yii 2.0版本框架的7个理由 http://blog.chedushi.com/archives/8988 刚接触Yii谈一下对Yii框架的看法和感受 http://bbs.csdn.net/ ...

  7. JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue

    前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的 ...

  8. JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序

    前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...

  9. JavaSE中Map框架学习笔记

    前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...

随机推荐

  1. GhostScript命令参数详解(转)

    http://blog.csdn.net/catoop/article/details/42737441 本文列出几个常用参数,然后下面附上官方的参数详解: 一.常用参数解释 这是一个测试的命令:gs ...

  2. 《剑指Offer》-006 - Java版快速幂 -解决n的m次方的问题

    #### 如题 (总结要点) 原文链接 : 1.主题 package blank; /** * 类的详细说明 给定一个double类型的浮点数base和int类型的整数exponent.求base的e ...

  3. mysql-mysqldump

    备份(导出)所有数据库的数据和结构(注意:这种方式备份,还原时,无需先创建数据库,可直接导入) mysqldump -u root -p 'password' --all-databases > ...

  4. ovirt常用后台维护命令

    以下命令是在node主机上操作 查看hosted-engine虚机的状态 hosted-engine --vm-status 启动hosted-engine虚机 hosted-engine --vm- ...

  5. 【Centos】桌面安装(转)

    链接:https://www.bnxb.com/linuxserver/27457.html 正常我们在使用CENTOS时候都是不会去用到它的GUI桌面系统,都是用最基础的命令行形式,这样会比较节省服 ...

  6. java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

    java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 是引用对象的地址值不能变,引用变量所指向的对象的内容是可以改变. final变量永远指向这个对象,是一个常量指针,而 ...

  7. Boring counting HDU - 3518 (后缀数组)

    Boring counting \[ Time Limit: 1000 ms \quad Memory Limit: 32768 kB \] 题意 给出一个字符串,求出其中出现两次及以上的子串个数,要 ...

  8. luogu_1156: 垃圾陷阱

    洛谷1156:垃圾陷阱 题目描述: 一头牛在一个井里,深度为\(D(1\leq D\leq100)\) 每过一段时间会往井里投掷一个物品,牛可以选择将其堆起来或者吃掉,吃掉可以增加生命值(生命值随时间 ...

  9. [RN] React Native 使用 FlatList 和 ScrollView 的下拉刷新问题

    React Native 使用 FlatList 和 ScrollView 实现 下拉刷新时,RefreshControl 控件不起作用, 后来经查明,原来 RefreshControl 要加在 Sc ...

  10. 前端零基础入门:页面结构层HTML(3)

    搭建网页HTML结构 标签 标签 块级标签 和 行内标签 标签嵌套规则 和 div css 标签是一个区块容器标记, 之间是一个容器,可以包含段落,表格,图片等各种HTML元素. 标签没有实际意义,为 ...