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. vue学习-自动行合并的table

    测试的效果 测试的html源码截图 v-table在tableGroup.js中定义,以下就render方法,行的所有单元格都在tableGrouper.js中处理 render:function(h ...

  2. 反编译看java for-each循环

    java 1.5发行版引入的for-each循环.(引自<Effective Java>中文版第二版 第46条) 如以下对数组列表的for-each循环示例: public class F ...

  3. android-读取MediaProvider

    1.MediaProvider存储手机中的媒体文件,用 SQLite 数据库存储图片.视频.音频等多媒体文件的信息,供视频播放器.音乐播放器.图库使用.以 root 权限进入 adb shell,使用 ...

  4. msfconlose基本命令

    命令 简介 back 从当前上下文 banner 显示显示一个令人敬畏的metasploit横幅 cd 更改当前工作目录 color 切换颜色 connect 与主机通信 edit 使用$ VISUA ...

  5. .NET默认一个客户端对同一个服务器地址同时只能建立2个TCP连接

    做一个客户端的测试小程序测试web service的并发处理.开始用async task做,不管创建多少个task,用netstat看同时只有两个tcp连接.以为是async task的问题,改用Ba ...

  6. NLP文本相似度

    NLP文本相似度 相似度 相似度度量:计算个体间相似程度 相似度值越小,距离越大,相似度值越大,距离越小 最常用--余弦相似度:​ 一个向量空间中两个向量夹角的余弦值作为衡量两个个体之间差异的大小 余 ...

  7. Node.js中实现套接字服务

    后端服务的一个重要的部分是通过套接字进行通信的能力. 套接字允许一个进程通过一个IP地址和端口与另一个进程通信 同一个服务器上的两个不同进程的进程间通信(IPC)或者访问一个完全不同 的服务器上运行的 ...

  8. spring 单元测试方法及其错误整理

    spring 单元测试及其错误整理 目录: NO1 spring单元测试方法 - NO1.1 pom.xml文件中确认有下面依赖 - NO1.2 在需要测试的类上,或者新建的测试类上添加注解 - NO ...

  9. CS61B HW0

    The Enhanced For Loop public class EnhancedForBreakDemo { public static void main(String[] args) { S ...

  10. [转] An Introduction to Mutual SSL Authentication

    1. Introduction Mutual SSL authentication or certificate based mutual authentication refers to two p ...