Go实战--通过httprouter和redis框架搭建restful api服务(github.com/julienschmidt/httprouter)
2017-08-14 16:35
1051 查看
生命不止,继续 go go go !!!
博客《Go实战–通过gin-gonic框架搭建restful api服务(github.com/gin-gonic/gin)》跟大家介绍了使用gin+mysql搭建一个restful api服务,今天主要介绍的是httprouter+redis搭建restful api服务。
github地址:
https://github.com/julienschmidt/httprouter
获取:
应用:
Go实战–golang中使用redis(redigo和go-redis/redis)
https://medium.com/code-zen/rest-apis-server-in-go-and-redis-66e9cb80a71b
这里创建一个简单的博客系统,具有以下功能:
http://localhost/ 显示欢迎消息,
http://localhost/posts 显示所有posts
http://localhost/posts/id 根据id显示post
首先是写model:
models.go
如果你对于golang中结构体不是很了解,可以看看这篇博客:
《Go语言学习之struct(The way to go)》
主要是字段标签
routes.go
列出所有的路由:
handlers.go
有路由就要有handler。
关于io/ioutil请参考下面博客:
《Go语言学习之ioutil包(The way to go)》
关于log包请参考下面博客:
《Go语言学习之log包(The way to go)》
router.go
db.go
最后就是数据库相关操作了,这里使用redis。
这里需要注意的就是string到json的转换。
关于strconv的用法可以参考博客:
《Go语言学习之strconv包(The way to go)》
例如,将整数转换为十进制字符串形式
func Itoa(i int) string
关于json的用法可以参考博客:
《Go语言学习之encoding/json包(The way to go)》
关于time包的用法可以参考博客:
《Go语言学习之time包(获取当前时间戳等)(the way to go)》
例如:获取当前时间
下面是db的完整代码:
最后运行结果:
博客《Go实战–通过gin-gonic框架搭建restful api服务(github.com/gin-gonic/gin)》跟大家介绍了使用gin+mysql搭建一个restful api服务,今天主要介绍的是httprouter+redis搭建restful api服务。
httprouter
HttpRouter is a lightweight high performance HTTP request router (also called multiplexer or just mux for short) for Go.github地址:
https://github.com/julienschmidt/httprouter
获取:
go get github.com/julienschmidt/httprouter
应用:
package main import ( "fmt" "log" "net/http" "github.com/julienschmidt/httprouter" ) func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { fmt.Fprint(w, "Welcome!\n") } func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name")) } func main() { router := httprouter.New() router.GET("/", Index) router.GET("/hello/:name", Hello) log.Fatal(http.ListenAndServe(":8080", router)) }
redigo/redis
golang中使用redis这里不再过多的介绍,之前的博客有写过:Go实战–golang中使用redis(redigo和go-redis/redis)
package main import ( "fmt" "github.com/garyburd/redigo/redis" ) func main() { c, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { fmt.Println("Connect to redis error", err) return } defer c.Close() _, err = c.Do("SET", "mykey", "superWang") if err != nil { fmt.Println("redis set failed:", err) } username, err := redis.String(c.Do("GET", "mykey")) if err != nil { fmt.Println("redis get failed:", err) } else { fmt.Printf("Get mykey: %v \n", username) } }
搭建rest api
参考地址:https://medium.com/code-zen/rest-apis-server-in-go-and-redis-66e9cb80a71b
这里创建一个简单的博客系统,具有以下功能:
http://localhost/ 显示欢迎消息,
http://localhost/posts 显示所有posts
http://localhost/posts/id 根据id显示post
首先是写model:
models.go
如果你对于golang中结构体不是很了解,可以看看这篇博客:
《Go语言学习之struct(The way to go)》
主要是字段标签
package main import ( "time" ) type User struct { Id int `json:"id"` Username string `json:"username"` Email string `json:"email"` } type Comment struct { Id int `json:"id"` User User `json:"user"` Text string `json:"text"` Timestamp time.Time `json:"timestamp"` } type Post struct { Id int `json:"id"` User User `json:"user"` Topic string `json:"topic"` Text string `json:"text"` Comment Comment `json:"comment"` Timestamp time.Time `json:"timestamp"` } type Posts []Post type Comments []Comment type Users []User
routes.go
列出所有的路由:
package main import ( mux "github.com/julienschmidt/httprouter" ) type Route struct { Name string Method string Pattern string Handle mux.Handle } type Routes []Route var routes = Routes{ Route{ "Index", "GET", "/", Index, }, Route{ "PostIndex", "GET", "/posts", PostIndex, }, Route{ "PostShow", "GET", "/posts/:postId", PostShow, }, Route{ "PostCreate", "POST", "/posts", PostCreate, }, Route{ "PostDelete", "POST", "/posts/del/:postId", PostDelete, }, }
handlers.go
有路由就要有handler。
关于io/ioutil请参考下面博客:
《Go语言学习之ioutil包(The way to go)》
关于log包请参考下面博客:
《Go语言学习之log包(The way to go)》
package main import ( "encoding/json" "fmt" "net/http" "io" "io/ioutil" "strconv" "log" "time" mux "github.com/julienschmidt/httprouter" ) func Logger(r *http.Request) { start:= time.Now() log.Printf( "%s\t%s\t%q\t%s", r.Method, r.RequestURI, r.Header, time.Since(start), ) } func Index(w http.ResponseWriter, r *http.Request, _ mux.Params) { fmt.Fprintf(w, "<h1 style=\"font-family: Helvetica;\">Hello, welcome to blog service</h1>") } func PostIndex(w http.ResponseWriter, r *http.Request, _ mux.Params) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) var posts Posts posts = FindAll() if err := json.NewEncoder(w).Encode(posts); err != nil { panic(err) } } func PostShow(w http.ResponseWriter, r *http.Request, ps mux.Params) { id, err := strconv.Atoi(ps.ByName("postId")) HandleError(err) post := FindPost(id) if err := json.NewEncoder(w).Encode(post); err != nil { panic(err) } } func PostCreate(w http.ResponseWriter, r *http.Request, _ mux.Params) { Logger(r) var post Post body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576)) HandleError(err) if err := r.Body.Close(); err != nil { panic(err) } // Save JSON to Post struct if err := json.Unmarshal(body, &post); err != nil { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(422) // unprocessable entity if err := json.NewEncoder(w).Encode(err); err != nil { panic(err) } } CreatePost(post) w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusCreated) } func PostDelete(w http.ResponseWriter, r *http.Request, ps mux.Params) { id, err := strconv.Atoi(ps.ByName("postId")) HandleError(err) DeletePost(id) }
router.go
package main import ( mux "github.com/julienschmidt/httprouter" ) func NewRouter() *mux.Router { router := mux.New() for _, route := range routes { router.Handle(route.Method, route.Pattern, route.Handle) } return router }
db.go
最后就是数据库相关操作了,这里使用redis。
这里需要注意的就是string到json的转换。
关于strconv的用法可以参考博客:
《Go语言学习之strconv包(The way to go)》
例如,将整数转换为十进制字符串形式
func Itoa(i int) string
关于json的用法可以参考博客:
《Go语言学习之encoding/json包(The way to go)》
关于time包的用法可以参考博客:
《Go语言学习之time包(获取当前时间戳等)(the way to go)》
例如:获取当前时间
func Now() Time
下面是db的完整代码:
package main import ( "fmt" "time" "encoding/json" "strconv" "github.com/garyburd/redigo/redis" ) var currentPostId int var currentUserId int func RedisConnect() redis.Conn { c, err := redis.Dial("tcp", ":6379") HandleError(err) return c } // Give us some seed data func init() { CreatePost(Post{ User: User{ Username: "wangshubo", Email: "wangshubo1989@126.com", }, Topic: "My First Post", Text: "Hello everyone! This is awesome.", }) CreatePost(Post{ User: User{ Username: "superWang", Email: "wangshubo@gmail.com", }, Topic: "Greeting", Text: "Greetings from Ironman", }) } func FindAll() Posts { c := RedisConnect() defer c.Close() keys, err := c.Do("KEYS", "post:*") HandleError(err) var posts Posts for _, k := range keys.([]interface{}) { var post Post reply, err := c.Do("GET", k.([]byte)) HandleError(err) if err := json.Unmarshal(reply.([]byte), &post); err != nil { panic(err) } posts = append(posts, post) } return posts } func FindPost(id int) Post { var post Post c := RedisConnect() defer c.Close() reply, err := c.Do("GET", "post:" + strconv.Itoa(id)) HandleError(err) fmt.Println("GET OK") if err = json.Unmarshal(reply.([]byte), &post); err != nil { panic(err) } return post } func CreatePost(p Post) { currentPostId += 1 currentUserId += 1 p.Id = currentPostId p.User.Id = currentUserId p.Timestamp = time.Now() c := RedisConnect() defer c.Close() b, err := json.Marshal(p) HandleError(err) // Save JSON blob to Redis reply, err := c.Do("SET", "post:" + strconv.Itoa(p.Id), b) HandleError(err) fmt.Println("GET ", reply) } func DeletePost(id int) { c := RedisConnect() defer c.Close() reply, err := c.Do("DEL", "post:" + strconv.Itoa(id)) HandleError(err) if reply.(int) != 1 { fmt.Println("No post removed") } else { fmt.Println("Post removed") } }
最后运行结果:
相关文章推荐
- Go实战--通过gin-gonic框架搭建restful api服务(github.com/gin-gonic/gin)
- go服务端----使用dotweb框架搭建简易服务
- golang实战使用gin+xorm搭建go语言web框架restgo详解3 系统常用配置参数
- golang实战使用gin+xorm搭建go语言web框架restgo详解9 session、日志、鉴权、验证码等
- golang实战使用gin+xorm搭建go语言web框架restgo详解10 使用restgo搭建后台管理系统
- golang实战使用gin+xorm搭建go语言web框架restgo详解4 路由配置
- golang实战使用gin+xorm搭建go语言web框架restgo详解5 控制器C
- java程序员10分钟可上手的golang框架golang实战使用gin+xorm搭建go语言web框架restgo
- 框架 day80 涛涛商城项目-redis安装单机版solr,搭建搜索服务层,solrJ使用
- Go实战--通过basic认证的http(basic authentication)
- 通过NodeJS,Express搭建本地HTTP访问服务.
- 使用CodeIgniter框架搭建RESTful API服务
- golang实战使用gin+xorm搭建go语言web框架restgo详解5.2 跳转和重定向
- go语言 通过http包搭建简单web服务器 对http包源码的略微分析
- golang实战使用gin+xorm搭建go语言web框架restgo详解5.3 资源控制器
- golang实战使用gin+xorm搭建go语言web框架restgo详解5.4 控制器参数绑定
- golang实战使用gin+xorm搭建go语言web框架restgo详解5.5 控制器模型绑定
- 实施微服务,我们需要哪些基础框架http://www.open-open.com/news/view/b7463e
- Go实战--golang中使用echo框架中的HTTP/2、Server Push(labstack/echo、golang.org/x/net/http2)
- golang实战使用gin+xorm搭建go语言web框架restgo详解5.6 控制器参数校验