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-cli入门

    这也仅仅是入门而已了☺ 自己也在慢慢学习中,不对的地方希望大佬可以多多指教,请不吝赐教,感激不尽. 这章主要是搭建环境: 1.安装node环境 从官网下载并安装node,傻瓜操作,安装完成之后,命令行 ...

  2. unic

    在线考试 答题剩余时间0小时51分18秒 考生须知 1.本次考试结束后,剩余补考次数:2次 2.考试时间为60分钟,超时系统自动交卷 3.本次考试满分100分(5*20道),60分通过考试 1. (单 ...

  3. ES6学习:两个面试题目--关于模板字符串

    号称看完就能“让开发飞起来”,不过文中的两个面试题目的知识点并没包括在文中. https://www.jianshu.com/p/287e0bb867ae 文中并没有完整的知识点去完成上面的两道题,这 ...

  4. let,const,var

    1.const定义的变量不可以修改,而且必须初始化. 1 const b = 2;//正确 2 // const b;//错误,必须初始化 3 console.log('函数外const定义b:' + ...

  5. SVN完全备份,增量备份,库同步

    svn备份一般采用三种方式:1)svnadmin dump 2)svnadmin hotcopy 3)svnsync. 优缺点分析: ============== 第一种svnadmin hotcop ...

  6. Python学习笔记-函数基础

    函数基础 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 为什么使用函数:减少重复代码.使程序变的可扩展使程序变得易维护 1.定义一个函数 #定 ...

  7. spring整合mybatis二种配置

    第一种: <!-- 配置sqlsession --> <bean id="sqlsessionFactory" class="org.mybatis.s ...

  8. Java的BIO,NIO和AIO的区别于演进

    作者:公众号:我是攻城师 前言 Java里面的IO模型种类较多,主要包括BIO,NIO和AIO,每个IO模型都有不一样的地方,那么这些IO模型是如何演变呢,底层的原理又是怎样的呢? 本文我们就来聊聊. ...

  9. FFmpeg命令行工具学习(二):播放媒体文件的工具ffplay

    一.简述 ffplay是以FFmpeg框架为基础,外加渲染音视频的库libSDL构建的媒体文件播放器. 在使用ffplay之前必须要安装到系统中,MAC的安装教程为:http://www.cnblog ...

  10. Java核心技术卷一基础知识-第5章-继承-读书笔记

    第5章 继承 本章内容: * 类.超类和子类 * Object:所有类的超类 * 泛型数组列表 * 对象包装器和自动装箱 * 参数数量可变的方法 * 枚举类 * 反射 * 继承设计的技巧 利用继承,人 ...