设为首页 加入收藏

TOP

Go Web:RESTful web service示例(一)
2018-12-07 14:13:31 】 浏览:246
Tags:Web RESTful web service 示例

RESTful架构的简介

web服务的架构模式主要有2种:SOAP和REST。SOAP和REST都回答了同一个问题:如何访问web服务。

SOAP风格的程序是功能驱动的,要借助xml来传递数据,明确表示要做什么动作,访问什么资源,但使用xml是非常繁琐复杂的事情。

RESTful风格的Web服务是资源驱动的,通过资源(名词)和http方法GET/POST/DELETE/PUT来实现增删改查的逻辑,偶尔也用PATCH/HEAD方法。注意,POST不是幂等的,而PUT是幂等的,所以PUT常用来更新资源,POST常用来创建资源。

关于RESTful风格的web服务,重点体现在URI上。RESTful风格的web服务的URI不能包含动词,而是只包含名词(资源)。动词或其它相关的意思可以通过http request的header/body或者通过url的query来传递。

例如:
1.获取id=1的文章:/posts/show/1,其中show是动词,这个URI就设计错了,正确的写法应该是/posts/1,然后用GET方法表示获取,即show
2.用户1转账500给2:POST /accounts/1/transfer/500/to/2,transfer是动词,是错误的,应该设计成名词,并将动词逻辑相关的参数通过URL的query或者请求报文传递

POST /transaction HTTP/1.1
Host: 127.0.0.1
  
from=1&to=2&amount=500.00

关于RESTful的web,参见阮一峰的两篇文章:

RESTful风格的web服务示例

本示例是描述如何操作博客文章的web服务,对于RESTful的规范来说,功能并不完善,但对于理解RESTful来说足够了。

两个源码文件server.go和data.go位于同个目录下,都属于main包,server.go是运行入口,data.go是数据操作逻辑的代码。

以下是server.go文件内容,定义handler。注意处理资源的方式,这是RESTful风格的web服务核心:URI中不能包含动词,只通过资源来完成动作逻辑

package main

import (
    "encoding/json"
    "net/http"
    "path"
    "strconv"
)

func main() {
    server := http.Server{
        Addr: "127.
		    

0.0.1:8080", } http.HandleFunc("/posts/", handleRequest) server.ListenAndServe() } func handleRequest(w http.ResponseWriter, r *http.Request) { var err error switch r.Method { case "GET": err = handleGet(w, r) case "POST": err = handlePost(w, r) case "PUT": err = handlePut(w, r) case "DELETE": err = handleDelete(w, r) } if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } func handleGet(w http.ResponseWriter, r *http.Request) (err error) { id, err := strconv.Atoi(path.Base(r.URL.Path)) if err != nil { return } post, err := retrieve(id) if err != nil { return } output, err := json.MarshalIndent(&post, "", "\t\t") if err != nil { return } w.Header().Set("Content-Type", "application/json") w.Write(output) return } func handlePost(w http.ResponseWriter, r *http.Request) (err error) { len := r.ContentLength body := make([]byte, len) r.Body.Read(body) var post Post json.Unmarshal(body, &post) err = post.create() if err != nil { return } w.WriteHeader(200) return } func handlePut(w http.ResponseWriter, r *http.Request) (err error) { id, err := strconv.Atoi(path.Base(r.URL.Path)) if err != nil { return } post, err := retrieve(id) if err != nil { return } len := r.ContentLength body := make([]byte, len) r.Body.Read(body) json.Unmarshal(body, &post) err = post.update() if err != nil { return } w.WriteHeader(200) return } func handleDelete(w http.ResponseWriter, r *http.Request) (err error) { id, err := strconv.Atoi(path.Base(r.URL.Path)) if err != nil { return } post, err := retrieve(id) if err != nil { return } err = post.delete() if err != nil { return } w.WriteHeader(200) return }

以下是操作数据库的data.go文件内容:

package main

import (
    "database/sql"

    _ "github.com/go-sql-driver/mysql"
)

type Post struct {
    Id      int    `json:"id"`
    Content string `json:"content"`
    Author  string `json:"author"`
}

var Db *sql.DB

func init() {
    var err error
    Db, err = sql.Open("m
			
		  
编程开发网
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Golang中的三个点 下一篇Go处理json数据

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(217) }