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("mysql", "root:P@ssword1!@tcp(192.168.100.21:3306)/blog")
if err != nil {
panic(err)
}
} func retrieve(id int) (post Post, err error) {
post = Post{}
err = Db.QueryRow("select id, content, author from posts where id = ?", id).Scan(&post.Id, &post.Content, &post.Author)
return
} func (post *Post) create() (err error) {
statement := "insert into posts (content, author) values (?, ?)"
stmt, err := Db.Prepare(statement)
if err != nil {
return
}
defer stmt.Close()
res, err := stmt.Exec(post.Content, post.Author)
if err != nil {
return
}
lastid, err := res.LastInsertId()
if err != nil {
return
}
post.Id = int(lastid)
return
} func (post *Post) update() (err error) {
_, err = Db.Exec("update posts set content = ?, author = ? where id = ?", post.Content, post.Author, post.Id)
return
} func (post *Post) delete() (err error) {
_, err = Db.Exec("delete from posts where id = ?", post.Id)
return
}

Go Web:RESTful web service示例的更多相关文章

  1. 使用Java创建RESTful Web Service

    REST是REpresentational State Transfer的缩写(一般中文翻译为表述性状态转移).2000年Roy Fielding博士在他的博士论文“Architectural Sty ...

  2. JAX-RS 方式的 RESTful Web Service 开发

    JAX-RS 方式的 RESTful Web Service 开发 ——基于 CXF+Spring 的实现 Web Service 目前在风格上有两大类,一个是基于 SOAP 协议,一个是完全遵循 H ...

  3. 使用Java创建RESTful Web Service(转)

    REST是REpresentational State Transfer的缩写(一般中文翻译为表述性状态转移).2000年Roy Fielding博士在他的博士论文“Architectural Sty ...

  4. day01(RESTful Web Service、SVN)

    今日大纲 搭建SSM环境 基于SSM环境实现用户管理系统 学习RESTful Web Service 学习SVN 统一开发环境 JDK1.7 32? 64? -- 64 Eclipse 使用4.4.1 ...

  5. 如何使用 JMeter 调用你的 Restful Web Service?进行简单的压力测试和自动化测试

    表述性状态传输(REST)作为对基于 SOAP 和 Web 服务描述语言(WSDL)的 Web 服务的简单替代,在 Web 开发上得到了广泛的接受.能够充分证明这点的是主流 Web 2.0 服务提供商 ...

  6. Spring Boot 构建一个 RESTful Web Service

    1  项目目标: 构建一个 web service,接收get 请求 http://localhost:8080/greeting 响应一个json 结果: {"id":1,&qu ...

  7. 【转】基于CXF Java 搭建Web Service (Restful Web Service与基于SOAP的Web Service混合方案)

    转载:http://www.cnblogs.com/windwithlife/archive/2013/03/03/2942157.html 一,选择一个合适的,Web开发环境: 我选择的是Eclip ...

  8. 【转】 Build a RESTful Web service using Jersey and Apache Tomcat 2009

    Build a RESTful Web service using Jersey and Apache Tomcat Yi Ming Huang with Dong Fei Wu, Qing GuoP ...

  9. Building a RESTful Web Service Using Spring Boot In Eclipse

    一.构建restful web service 创建Maven的java web工程,maven的pom文件加入依赖包 创建包hello Greeting.java package hello; pu ...

  10. (转)接口自动化测试 – Java+TestNG 测试 Restful Web Service

    本文主要介绍如何用Java针对Restful web service 做接口自动化测试(数据驱动),相比UI自动化,接口自动化稳定性可靠性高,实施难易程度低,做自动化性价比高.所用到的工具或类库有 T ...

随机推荐

  1. SSRF

    SSRF 关于SSRF SSRF(Server-Side Request Forgery:服务器端请求伪造),攻击者通过伪造服务器端发起的请求,获取客户端所不能得到的数据.一般情况下,SSRF攻击的目 ...

  2. python循环解压rar文件

    python循环解压rar文件 C:. │ main.py │ ├─1_STL_算法简介 │ STL_算法简介.rar │ └─2_STL_算法_填充新值 STL_算法_填充新值.rar 事情是这样的 ...

  3. Shader_ShaderForge_NGUI_序列帧/

    序列帧 Shader篇 Shader Forge序列帧算法! 附上Shader代码部分: // Shader created with Shader Forge v1.26 // Shader For ...

  4. 自兴人工智能 python特点了解

    计算机语言从语言执行分类来看,大概可分为编译型语言(如Java.c++)和解释型语言(如python.javascript) 1.编译型语言  java   c++ 编写源代码.java ---> ...

  5. 搭建vue环境

    1. 下载安装nodejs 截至2018-06-05 最新稳定版本为 8.11.2,直接 next ,不改目录. PS C:\Users\Administrator> node -v v8.11 ...

  6. 背水一战 Windows 10 (113) - 锁屏: 将 Application 的 Badge 通知和 Tile 通知发送到锁屏, 将 secondary tile 的 Badge 通知和 Tile 通知发送到锁屏

    [源码下载] 背水一战 Windows 10 (113) - 锁屏: 将 Application 的 Badge 通知和 Tile 通知发送到锁屏, 将 secondary tile 的 Badge ...

  7. 如何用kaldi做孤立词识别三

    这次wer由15%下降到0%了,后面跑更多的模型 LOG (apply-cmvn[5.2.124~1396-70748]:main():apply-cmvn.cc:162) Applied cepst ...

  8. 使用node自动生成html并调用cmd命令提交代码到仓库

    生成html提交到git仓库 基于目前的express博客,写了一点代码,通过request模块来请求站点,将html保存到coding-pages目录,复制静态文件夹到coding-pages,最后 ...

  9. 站在JAVA数据结构的视角看待简单表结构

    1.前言: 我们提到程序中的集合的时候,往往脑海中会浮现出, 如ArrayList和LinkedList以及和HashMap.当然在提到ArrayList和LinkedList的时候,我们大多数的人都 ...

  10. 盘点和反思在微信的阴影下艰难求生的移动端IM应用

    本文原作者:李越,由银杏财经原创发布,本次内容改动. 1.前言 上线一周完成1.5亿元融资,上线10天总激活用户数超400万,8月29日单日新增用户超100万,这是子弹短信交出的最新成绩单(详见< ...