生命不止,继续 go go go !!!
##**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/httproute
获取:
go get github.com/julienschmidt/httproute
应用:
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 []Use
**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包请参考下面博客:
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 route
}
**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")
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。