RESTful风格

带着问题,找答案:

通过本片文章,你会了解以下四点 。并且我会给出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动词变换 进行不同的操作

Go 复制代码
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)
}

2、基础版:

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

Go 复制代码
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)
}
原理图:
bash 复制代码
  客户端 (浏览器/curl)
       │
       ▼
  HTTP请求(GET/POST)
       │
       ▼
  Go服务器 (main.go)
       │
       ├── GET /users → 返回用户列表
       │
       └── POST /users → 创建新用户
       │    ├── 解析JSON
       │    ├── 验证数据
       │    └── 添加到内存
       │
       ▼
  HTTP响应(JSON数据)

3、进阶版:

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

Go 复制代码
// 在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)
}

恭喜走出新手村!

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

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


谨记:

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

目标是简单、统一、好扩展。
简称:"动词操作资源地址",记住这点,你对restful的理解就能掌握90%了

相关推荐
超级小忍7 分钟前
服务端向客户端主动推送数据的几种方法(Spring Boot 环境)
java·spring boot·后端
字节跳跃者9 分钟前
为什么Java已经不推荐使用Stack了?
javascript·后端
字节跳跃者9 分钟前
深入剖析HashMap:理解Hash、底层实现与扩容机制
javascript·后端
程序无bug11 分钟前
Spring IoC注解式开发无敌详细(细节丰富)
java·后端
程序无bug13 分钟前
Spring 对于事务上的应用的详细说明
java·后端
食亨技术团队15 分钟前
被忽略的 SAAS 生命线:操作日志有多重要
java·后端
程序员NEO15 分钟前
精控Spring AI日志
人工智能·后端
考虑考虑31 分钟前
Maven 依赖范围(Scope)
java·后端·maven
张小洛38 分钟前
Spring AOP 设计解密:代理对象生成、拦截器链调度与注解适配全流程源码解析
java·后端·spring·spring aop·aop
00后程序员43 分钟前
iOS 性能测试工具全流程:主流工具实战对比与适用场景
后端