RESTful风格

简介: 小白只要记好一句话:RESTful = 用HTTP动词(GET/POST...)操作网络资源(URI标识),目标是简单、统一、好扩展。简称:"动词操作资源地址",记住这点,你对restful的理解就能掌握90%了

带着问题,找答案:

通过本片文章,你会了解以下四点。并且我会给出go语言的实现案例。

1、了解restful风格的来源、起源、演变史

2、了解restful风格的定义、含义

3、掌握restful风格的简单运用

4、做一个小demo

在restful中前进,是一个非常有趣的过程。

一、他打哪来?为解决什么而去?

1、他爹是谁?

是个叫Roy Fielding的博士,是曾经参与开发http协议(现在上网的基础规则)的主力之一。

2、为啥发明?

2000年那会,网上资源凌乱不堪。传递信息时。前后端交互时,乱操作http (如:用GET、POST乱传参数)。大佬不愧是大佬,roy fielding博士,敏锐的发现这一点。并在自己的论文中书写出了一种规则(风格)。试图平息这场混乱。(“让网络资源,能像图书馆中的书记一样管理”)

目标是:让Web服务 简单可扩展(加服务器就能扛更多人访问)、无状态(服务器不记仇,每次请求独立)

二、restful的具体表现?

1、一切皆“资源”

互联网上的(用户、订单、图片...),每个资源都有一个唯一地址(URL),

比如: http://api.com/users (代表所有用户)

2、用HTTP动词操作资源

动作 HTTP动词 例子 作用
GET GET /users/101 获取101号用户信息
POST POST /users 创建新用户
改(全量) PUT PUT /users/101 更新101号全部信息
DELETE DELETE /users/101 删除101号用户
改(局部) PATCH PATCH /users/101 只改用户昵称

3、返回必带状态码

  • 200 ok:成功
  • 201 Created:创建成功
  • 404 Not Found:资源不存在

....

三、Restful的意义!

1、结束的时代,从前url随意设定。如:/getUser?id=1、/delete_order?oid=2...

    现在通过URL+HTTP动词,让全天下的程序员都能看懂。

2、只要按照这一套标准、这同一种风格。无论是go还是C、C++、Java等其他语言。都能通过接口调用,流畅的配合实现某种功能。

3、幂等安全:幂-就是多次。同一操作,连续执行多次,效果是一样的。如delete一个条数据多次,效果与仅delete一次,是相同的。

在进行实战演练前,你需要掌握(go基础知识、http相关知识、数据库相关知识)

四、实战演练

跟着本博主的思路,一点一点来,包教会。

第一步:通过一个及其简单的代码入门。

1、入门版:

目标:掌握·通过http动词变换进行不同的操作

package main
import (
  "encoding/json"
  "net/http"
)
// 用户结构体
type User struct {
  ID   int    `json:"id"`
  Name string `json:"name"`
}
// 内存存储(代替数据库)
var users = []User{
  {ID: 1, Name: "张三"},
  {ID: 2, Name: "李四"},
}
func main() {
  // 注册路由:处理 /users 的所有请求
  http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
    // 设置响应头(告诉客户端返回的是JSON)
    w.Header().Set("Content-Type", "application/json")
    
    switch r.Method {
    case "GET": // 获取用户列表
      json.NewEncoder(w).Encode(users)
      
    case "POST": // 创建新用户
      var newUser User
      // 解析客户端发来的JSON数据
      if err := json.NewDecoder(r.Body).Decode(&newUser); err != nil {
        w.WriteHeader(http.StatusBadRequest) // 400 错误
        return
      }
      // 模拟ID生成
      newUser.ID = len(users) + 1
      users = append(users, newUser)
      w.WriteHeader(http.StatusCreated) // 201 创建成功
      json.NewEncoder(w).Encode(newUser)
      
    default:
      w.WriteHeader(http.StatusMethodNotAllowed) // 405 不允许的方法
    }
  })
  // 启动服务器(端口8080)
  http.ListenAndServe(":8080", nil)
}

image.gif

2、基础版:

将入门版本的拓展开来:通过函数调用实现。

package main
import (
  "encoding/json" // 用于JSON处理
  "fmt"           // 格式化输出
  "log"           // 日志记录
  "net/http"      // HTTP服务
)
// 定义用户结构体(相当于数据模型)
type User struct {
  ID   int    `json:"id"`   // 用户ID
  Name string `json:"name"` // 用户名
}
// 内存数据库(暂时替代真实数据库)
var users = []User{
  {ID: 1, Name: "小明"},
  {ID: 2, Name: "小红"},
}
func main() {
  fmt.Println("👉 启动RESTful服务器: http://localhost:8080")
  
  // 注册路由:当访问 /users 时触发处理函数
  http.HandleFunc("/users", usersHandler)
  
  // 启动服务器(监听8080端口)
  log.Fatal(http.ListenAndServe(":8080", nil))
}
// 处理/users路由的请求
func usersHandler(w http.ResponseWriter, r *http.Request) {
  // 设置响应头(告诉浏览器返回的是JSON)
  w.Header().Set("Content-Type", "application/json")
  
  switch r.Method {
  case "GET": // 处理GET请求(查询用户)
    handleGetUsers(w, r)
    
  case "POST": // 处理POST请求(创建用户)
    handleCreateUser(w, r)
    
  default: // 其他请求方法不允许
    w.WriteHeader(http.StatusMethodNotAllowed) // 405错误
    fmt.Fprintf(w, `{"error": "不支持该方法"}`)
  }
}
// 处理GET请求(获取所有用户)
func handleGetUsers(w http.ResponseWriter, r *http.Request) {
  // 将用户列表转为JSON格式
  jsonData, err := json.Marshal(users)
  if err != nil {
    w.WriteHeader(http.StatusInternalServerError) // 500错误
    fmt.Fprintf(w, `{"error": "数据转换失败"}`)
    return
  }
  
  // 返回JSON数据
  w.Write(jsonData)
}
// 处理POST请求(创建新用户)
func handleCreateUser(w http.ResponseWriter, r *http.Request) {
  // 1. 解析请求中的JSON数据
  var newUser User
  err := json.NewDecoder(r.Body).Decode(&newUser)
  if err != nil {
    w.WriteHeader(http.StatusBadRequest) // 400错误
    fmt.Fprintf(w, `{"error": "无效的JSON数据"}`)
    return
  }
  
  // 2. 简单的数据验证
  if newUser.Name == "" {
    w.WriteHeader(http.StatusBadRequest)
    fmt.Fprintf(w, `{"error": "用户名不能为空"}`)
    return
  }
  
  // 3. 生成新ID(实际项目中数据库会自动生成)
  newUser.ID = len(users) + 1
  
  // 4. 添加到用户列表
  users = append(users, newUser)
  
  // 5. 返回创建成功的响应
  w.WriteHeader(http.StatusCreated) // 201状态码
  json.NewEncoder(w).Encode(newUser)
}

image.gif

原理图:

客户端 (浏览器/curl)
  HTTP请求(GET/POST)
  Go服务器 (main.go)
       ├── GET /users → 返回用户列表
       └── POST /users → 创建新用户
       │    ├── 解析JSON
       │    ├── 验证数据
       │    └── 添加到内存
  HTTP响应(JSON数据)

image.gif

3、进阶版:

添加获取单个用户功能GET / users / {id} )(如:get/users/1)

// 在main函数中添加新路由
func main() {
    // ...原有代码...
    http.HandleFunc("/users/", userHandler) // 添加带ID的路由
}
// 新增处理函数
func userHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    
    // 从路径中提取ID:/users/123 → 123
    idStr := strings.TrimPrefix(r.URL.Path, "/users/")
    id, err := strconv.Atoi(idStr)
    if err != nil {
        w.WriteHeader(http.StatusBadRequest)
        fmt.Fprintf(w, `{"error": "无效的用户ID"}`)
        return
    }
    
    // 查找用户
    var foundUser *User
    for _, u := range users {
        if u.ID == id {
            foundUser = &u
            break
        }
    }
    
    if foundUser == nil {
        w.WriteHeader(http.StatusNotFound) // 404
        fmt.Fprintf(w, `{"error": "用户不存在"}`)
        return
    }
    
    json.NewEncoder(w).Encode(foundUser)
}

image.gif


恭喜走出新手村!

到这里,差不多,大家就已经明白了Restful风格是什么?怎么用。

后续若抽出时间,我会继续更新呦~😉


谨记:

RESTful = 用HTTP动词(GET/POST...)操作网络资源(URI标识),

目标是简单、统一、好扩展。

简称:"动词操作资源地址",记住这点,你对restful的理解就能掌握90%了

目录
相关文章
|
5月前
|
消息中间件 NoSQL Redis
高可靠微服务消息设计:Outbox模式、延迟队列与Watermill集成实践
构建高可靠微服务,事件丢失和延迟任务一直是难题?本文带你从实战角度掌握 Outbox模式、延迟队列 及 Watermill+Redis Stream 集成方案,教你用Go打造可靠、可观测、毫秒级响应的事件驱动系统。
515 2
|
5月前
|
缓存 安全 测试技术
GO项目开发规范文档解读
本篇博客的目的,更多是为快速翻阅与回忆使用。
311 1
|
8月前
|
网络协议 安全 数据挖掘
阿里云服务器九代实例c9i/g9i/r9i与c9a/g9a/r9a对比,性能、价格、适用场景对比与选择参考
目前在阿里云的活动中,除了入门级的轻量应用服务器和经济型e实例,主打高性价比的通用算力型实例云服务器之外,对于需要高性能云服务器的用户,可选择活动内的九代云服务器c9i/g9i/r9i实例和c9a/g9a/r9a实例,本文为大家介绍c9i/g9i/r9i实例和c9a/g9a/r9a实例的架构、处理器、适用场景与价格,以供大家对比和选择参考。
1727 9
|
5月前
|
文字识别 NoSQL API
Go-Zero微服务实战:高并发场景下的学生认证系统设计与实现
在校园社交等垂直领域应用中,"学生身份认证"是构建信任体系的核心基石。本文将会基于 Go-Zero 微服务框架,详细拆解了一个生产级的学生认证系统实现。涵盖了 OCR 双通道故障转移、WebSocket 实时推送、事件驱动架构 (EDA)、敏感数据加密 以及 有限状态机(FSM) 的设计模式。
400 7
|
5月前
|
缓存 前端开发 JavaScript
首屏优化实践:如何将 Vue3 + Vite 项目的加载速度提升3倍
本篇博客,将会带着你,走一遍首屏优化实践。手把手给你演示,如何将 Vue3 + Vite 项目的加载速度提升3倍。
526 6
首屏优化实践:如何将 Vue3 + Vite 项目的加载速度提升3倍
|
5月前
|
网络安全 Go Docker
CI/CD全流程
记录 后端go 算法平台 / python 爬虫网关 / 前端vue项目 CI-CD部署流程
475 8
|
5月前
|
中间件 API Go
自go-zero走进微服务
Go-zero 的微服务进阶之路:始于 goctl 的契约驱动与提效,立于 zrpc 与 etcd 的架构互联,成于 熔断限流等全链路服务治理的坚实保障。
407 1
|
7月前
|
安全 数据安全/隐私保护
2026阿里云账号注册流程(以企业用户为例)注册材料、实名认证、企业上云补贴及问题解答FAQ
企业用户注册阿里云账号仅需手机号,注册后须完成实名认证方可使用。本文详解2026年最新企业账号注册、支付宝扫码快速认证流程及常见问题,助力企业高效上云,享最高百万出海补贴。
773 9
|
XML Java Android开发
Android自定义view之网易云推荐歌单界面
本文详细介绍了如何通过自定义View实现网易云音乐推荐歌单界面的效果。首先,作者自定义了一个圆角图片控件`MellowImageView`,用于绘制圆角矩形图片。接着,通过将布局放入`HorizontalScrollView`中,实现了左右滑动功能,并使用`ViewFlipper`添加图片切换动画效果。文章提供了完整的代码示例,包括XML布局、动画文件和Java代码,最终展示了实现效果。此教程适合想了解自定义View和动画效果的开发者。
566 65
Android自定义view之网易云推荐歌单界面

热门文章

最新文章