Skip to content

Commit 8ac3f39

Browse files
authored
Merge pull request astaxie#776 from vCaesar/u7-pr
Update RESTful and NoSQL
2 parents 2ec0093 + b7d9bf8 commit 8ac3f39

File tree

11 files changed

+539
-143
lines changed

11 files changed

+539
-143
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ QQ群:148647580
2121

2222
BBS:[http://golanghome.com/](http://gocn.io/)
2323

24+
##Contributors
25+
26+
- See [contributors page](https://github.com/astaxie/build-web-application-with-golang/graphs/contributors) for full list of contributors.
27+
2428
## Acknowledgments
2529

2630
- [四月份平民](https://plus.google.com/110445767383269817959) (review代码)

de/05.6.md

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,90 @@ redis is a key-value storage system like Memcached, that supports the string, li
1010

1111
There are some Go database drivers for redis:
1212

13+
- [https://github.com/garyburd/redigo](https://github.com/garyburd/redigo)
14+
- [https://github.com/go-redis/redis](https://github.com/go-redis/redis)
15+
- [https://github.com/hoisie/redis](https://github.com/hoisie/redis)
1316
- [https://github.com/alphazero/Go-Redis](https://github.com/alphazero/Go-Redis)
14-
- [http://code.google.com/p/tideland-rdc/](http://code.google.com/p/tideland-rdc/)
1517
- [https://github.com/simonz05/godis](https://github.com/simonz05/godis)
16-
- [https://github.com/hoisie/redis.go](https://github.com/hoisie/redis.go)
18+
19+
Let's see how to use the driver that redigo to operate on a database:
20+
21+
```Go
22+
23+
package main
24+
25+
import (
26+
"fmt"
27+
"github.com/garyburd/redigo/redis"
28+
"os"
29+
"os/signal"
30+
"syscall"
31+
"time"
32+
)
33+
34+
var (
35+
Pool *redis.Pool
36+
)
37+
38+
func init() {
39+
redisHost := ":6379"
40+
Pool = newPool(redisHost)
41+
close()
42+
}
43+
44+
func newPool(server string) *redis.Pool {
45+
46+
return &redis.Pool{
47+
48+
MaxIdle: 3,
49+
IdleTimeout: 240 * time.Second,
50+
51+
Dial: func() (redis.Conn, error) {
52+
c, err := redis.Dial("tcp", server)
53+
if err != nil {
54+
return nil, err
55+
}
56+
return c, err
57+
},
58+
59+
TestOnBorrow: func(c redis.Conn, t time.Time) error {
60+
_, err := c.Do("PING")
61+
return err
62+
},
63+
}
64+
}
65+
66+
func close() {
67+
c := make(chan os.Signal, 1)
68+
signal.Notify(c, os.Interrupt)
69+
signal.Notify(c, syscall.SIGTERM)
70+
signal.Notify(c, syscall.SIGKILL)
71+
go func() {
72+
<-c
73+
Pool.Close()
74+
os.Exit(0)
75+
}()
76+
}
77+
78+
func Get(key string) ([]byte, error) {
79+
80+
conn := Pool.Get()
81+
defer conn.Close()
82+
83+
var data []byte
84+
data, err := redis.Bytes(conn.Do("GET", key))
85+
if err != nil {
86+
return data, fmt.Errorf("error get key %s: %v", key, err)
87+
}
88+
return data, err
89+
}
90+
91+
func main() {
92+
test, err := Get("test")
93+
fmt.Println(test, err)
94+
}
95+
96+
```
1797

1898
I forked the last of these packages, fixed some bugs, and used it in my short URL service (2 million PV every day).
1999

de/08.3.md

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -68,49 +68,62 @@ The picture above shows three levels that are currently implemented in REST. You
6868

6969
We can simulate `PUT` and `DELETE` requests by adding a hidden `_method` field in our POST requests, however these requests must be converted on the server side before they are processed. My personal applications use this workflow to implement REST interfaces. Standard RESTful interfaces are easily implemented in Go, as the following example demonstrates:
7070

71+
```Go
72+
7173
package main
7274

7375
import (
7476
"fmt"
75-
"github.com/drone/routes"
77+
"github.com/julienschmidt/httprouter"
78+
"log"
7679
"net/http"
7780
)
7881

79-
func getuser(w http.ResponseWriter, r *http.Request) {
80-
params := r.URL.Query()
81-
uid := params.Get(":uid")
82+
func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
83+
fmt.Fprint(w, "Welcome!\n")
84+
}
85+
86+
func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
87+
fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
88+
}
89+
90+
func getuser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
91+
uid := ps.ByName("uid")
8292
fmt.Fprintf(w, "you are get user %s", uid)
8393
}
8494

85-
func modifyuser(w http.ResponseWriter, r *http.Request) {
86-
params := r.URL.Query()
87-
uid := params.Get(":uid")
95+
func modifyuser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
96+
uid := ps.ByName("uid")
8897
fmt.Fprintf(w, "you are modify user %s", uid)
8998
}
9099

91-
func deleteuser(w http.ResponseWriter, r *http.Request) {
92-
params := r.URL.Query()
93-
uid := params.Get(":uid")
100+
func deleteuser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
101+
uid := ps.ByName("uid")
94102
fmt.Fprintf(w, "you are delete user %s", uid)
95103
}
96104

97-
func adduser(w http.ResponseWriter, r *http.Request) {
98-
params := r.URL.Query()
99-
uid := params.Get(":uid")
100-
fmt.Fprint(w, "you are add user %s", uid)
105+
func adduser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
106+
// uid := r.FormValue("uid")
107+
uid := ps.ByName("uid")
108+
fmt.Fprintf(w, "you are add user %s", uid)
101109
}
102110

103111
func main() {
104-
mux := routes.New()
105-
mux.Get("/user/:uid", getuser)
106-
mux.Post("/user/:uid", modifyuser)
107-
mux.Del("/user/:uid", deleteuser)
108-
mux.Put("/user/", adduser)
109-
http.Handle("/", mux)
110-
http.ListenAndServe(":8088", nil)
112+
router := httprouter.New()
113+
router.GET("/", Index)
114+
router.GET("/hello/:name", Hello)
115+
116+
router.GET("/user/:uid", getuser)
117+
router.POST("/adduser/:uid", adduser)
118+
router.DELETE("/deluser/:uid", deleteuser)
119+
router.PUT("/moduser/:uid", modifyuser)
120+
121+
log.Fatal(http.ListenAndServe(":8080", router))
111122
}
112123

113-
This sample code shows you how to write a very basic REST application. Our resources are users, and we use different functions for different methods. Here, we imported a third-party package called `github.com/drone/routes`. We've already covered how to implement a custom router in previous chapters -the `drone/routes` package implements some very convenient router mapping rules that make it very convenient for implementing RESTful architecture. As you can see, REST requires you to implement different logic for different HTTP methods of the same resource.
124+
```
125+
126+
This sample code shows you how to write a very basic REST application. Our resources are users, and we use different functions for different methods. Here, we imported a third-party package called `github.com/julienschmidt/httprouter`. We've already covered how to implement a custom router in previous chapters -the `julienschmidt/httprouter` package implements some very convenient router mapping rules that make it very convenient for implementing RESTful architecture. As you can see, REST requires you to implement different logic for different HTTP methods of the same resource.
114127

115128
## Summary
116129

en/08.3.md

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -68,49 +68,62 @@ The picture above shows three levels that are currently implemented in REST. You
6868

6969
We can simulate `PUT` and `DELETE` requests by adding a hidden `_method` field in our POST requests, however these requests must be converted on the server side before they are processed. My personal applications use this workflow to implement REST interfaces. Standard RESTful interfaces are easily implemented in Go, as the following example demonstrates:
7070

71+
```Go
72+
7173
package main
7274

7375
import (
7476
"fmt"
75-
"github.com/drone/routes"
77+
"github.com/julienschmidt/httprouter"
78+
"log"
7679
"net/http"
7780
)
7881

79-
func getuser(w http.ResponseWriter, r *http.Request) {
80-
params := r.URL.Query()
81-
uid := params.Get(":uid")
82+
func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
83+
fmt.Fprint(w, "Welcome!\n")
84+
}
85+
86+
func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
87+
fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
88+
}
89+
90+
func getuser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
91+
uid := ps.ByName("uid")
8292
fmt.Fprintf(w, "you are get user %s", uid)
8393
}
8494

85-
func modifyuser(w http.ResponseWriter, r *http.Request) {
86-
params := r.URL.Query()
87-
uid := params.Get(":uid")
95+
func modifyuser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
96+
uid := ps.ByName("uid")
8897
fmt.Fprintf(w, "you are modify user %s", uid)
8998
}
9099

91-
func deleteuser(w http.ResponseWriter, r *http.Request) {
92-
params := r.URL.Query()
93-
uid := params.Get(":uid")
100+
func deleteuser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
101+
uid := ps.ByName("uid")
94102
fmt.Fprintf(w, "you are delete user %s", uid)
95103
}
96104

97-
func adduser(w http.ResponseWriter, r *http.Request) {
98-
params := r.URL.Query()
99-
uid := params.Get(":uid")
100-
fmt.Fprint(w, "you are add user %s", uid)
105+
func adduser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
106+
// uid := r.FormValue("uid")
107+
uid := ps.ByName("uid")
108+
fmt.Fprintf(w, "you are add user %s", uid)
101109
}
102110

103111
func main() {
104-
mux := routes.New()
105-
mux.Get("/user/:uid", getuser)
106-
mux.Post("/user/:uid", modifyuser)
107-
mux.Del("/user/:uid", deleteuser)
108-
mux.Put("/user/", adduser)
109-
http.Handle("/", mux)
110-
http.ListenAndServe(":8088", nil)
112+
router := httprouter.New()
113+
router.GET("/", Index)
114+
router.GET("/hello/:name", Hello)
115+
116+
router.GET("/user/:uid", getuser)
117+
router.POST("/adduser/:uid", adduser)
118+
router.DELETE("/deluser/:uid", deleteuser)
119+
router.PUT("/moduser/:uid", modifyuser)
120+
121+
log.Fatal(http.ListenAndServe(":8080", router))
111122
}
112123

113-
This sample code shows you how to write a very basic REST application. Our resources are users, and we use different functions for different methods. Here, we imported a third-party package called `github.com/drone/routes`. We've already covered how to implement a custom router in previous chapters -the `drone/routes` package implements some very convenient router mapping rules that make it very convenient for implementing RESTful architecture. As you can see, REST requires you to implement different logic for different HTTP methods of the same resource.
124+
```
125+
126+
This sample code shows you how to write a very basic REST application. Our resources are users, and we use different functions for different methods. Here, we imported a third-party package called `github.com/julienschmidt/httprouter`. We've already covered how to implement a custom router in previous chapters -the `julienschmidt/httprouter` package implements some very convenient router mapping rules that make it very convenient for implementing RESTful architecture. As you can see, REST requires you to implement different logic for different HTTP methods of the same resource.
114127

115128
## Summary
116129

es/05.6.md

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,90 @@ Al ser el lenguaje C del siglo XXI, Go tiene soporte para bases de datos NoSQL,
99
redis es un sistema de almacenamiento llave valor como Memcached, que soporta los tipos de cadenas, listas conjuntos y conjuntos ordenados.
1010

1111
Aquí están algunos de los manejadores de bases de datos para redis:
12-
12+
- [https://github.com/garyburd/redigo](https://github.com/garyburd/redigo)
13+
- [https://github.com/go-redis/redis](https://github.com/go-redis/redis)
14+
- [https://github.com/hoisie/redis](https://github.com/hoisie/redis)
1315
- [https://github.com/alphazero/Go-Redis](https://github.com/alphazero/Go-Redis)
14-
- [http://code.google.com/p/tideland-rdc/](http://code.google.com/p/tideland-rdc/)
1516
- [https://github.com/simonz05/godis](https://github.com/simonz05/godis)
16-
- [https://github.com/hoisie/redis.go](https://github.com/hoisie/redis.go)
17+
18+
Let's see how to use the driver that redigo to operate on a database:
19+
20+
```Go
21+
22+
package main
23+
24+
import (
25+
"fmt"
26+
"github.com/garyburd/redigo/redis"
27+
"os"
28+
"os/signal"
29+
"syscall"
30+
"time"
31+
)
32+
33+
var (
34+
Pool *redis.Pool
35+
)
36+
37+
func init() {
38+
redisHost := ":6379"
39+
Pool = newPool(redisHost)
40+
close()
41+
}
42+
43+
func newPool(server string) *redis.Pool {
44+
45+
return &redis.Pool{
46+
47+
MaxIdle: 3,
48+
IdleTimeout: 240 * time.Second,
49+
50+
Dial: func() (redis.Conn, error) {
51+
c, err := redis.Dial("tcp", server)
52+
if err != nil {
53+
return nil, err
54+
}
55+
return c, err
56+
},
57+
58+
TestOnBorrow: func(c redis.Conn, t time.Time) error {
59+
_, err := c.Do("PING")
60+
return err
61+
},
62+
}
63+
}
64+
65+
func close() {
66+
c := make(chan os.Signal, 1)
67+
signal.Notify(c, os.Interrupt)
68+
signal.Notify(c, syscall.SIGTERM)
69+
signal.Notify(c, syscall.SIGKILL)
70+
go func() {
71+
<-c
72+
Pool.Close()
73+
os.Exit(0)
74+
}()
75+
}
76+
77+
func Get(key string) ([]byte, error) {
78+
79+
conn := Pool.Get()
80+
defer conn.Close()
81+
82+
var data []byte
83+
data, err := redis.Bytes(conn.Do("GET", key))
84+
if err != nil {
85+
return data, fmt.Errorf("error get key %s: %v", key, err)
86+
}
87+
return data, err
88+
}
89+
90+
func main() {
91+
test, err := Get("test")
92+
fmt.Println(test, err)
93+
}
94+
95+
```
1796

1897
Realicé una bifurcación de el último de estos paquetes, arreglé algunos servicios y lo usé en mi sistema de acortado de urls (2 millones de peticiones por día).
1998

0 commit comments

Comments
 (0)