Menu
CoddyTech

回顾:REST API 模型

本课属于 Coddy GO 学习旅程的“面向对象编程”单元。第 78 课,共 107 课。

challenge icon

挑战

简单

让我们为博客平台构建一个 REST API 模型系统吧!你将创建结构良好的类型,让它们能够序列化为 JSON,并提供易读的字符串表示形式。这正是构建真实 API 响应时所需要的。

你将把代码分配到两个文件中:

  • models.go:定义 API 数据模型,并添加合适的 JSON 标签和字符串表示形式。

    创建一个 Author 结构体,包含 ID(int)、Name(string)和 Email(string)字段。将它们映射到 JSON 键 "id"、"name" 和 "email"。实现 String(),使其返回格式 [Name] <[Email]>。

    创建一个 Post 结构体,包含 ID(int)、Title(string)、Content(string)、Author(嵌套的 Author 结构体)和 Published(bool)。将它们映射到 "id"、"title"、"content"、"author" 和 "published"。Content 字段应使用 omitempty,这样内容为空时就不会出现在 JSON 中。实现 String(),使其返回 "[Title]" by [Author's String representation]。

    创建一个 APIResponse 结构体,包含 Success(bool)、Message(string)和 Data(Post)。将它们映射到 "success"、"message" 和 "data"。Message 字段应使用 omitempty。

  • main.go:构建 API 响应,并演示 JSON 输出和字符串表示形式。

    读取操作类型(json 或 display),然后读取帖子详情:帖子 ID、标题、内容、作者 ID、作者姓名、作者邮箱和发布状态(true 或 false)。

    对于 json:创建一个 APIResponse,其中 Success: true,并将 Post 作为数据(让 Message 保持为空)。将其转换为 JSON 并打印。

    对于 display:创建 Post,使用它的 String 方法打印,然后另起一行单独打印 Author。

将提供以下输入:

  • 第 1 行:操作类型(json 或 display)
  • 第 2 行:帖子 ID
  • 第 3 行:标题
  • 第 4 行:内容(可以为空)
  • 第 5 行:作者 ID
  • 第 6 行:作者姓名
  • 第 7 行:作者邮箱
  • 第 8 行:发布状态(true 或 false)

例如,给定:

json
1
Getting Started with Go
Learn the basics of Go programming
101
Jane Smith
jane@example.com
true

你的输出应为:

{"success":true,"data":{"id":1,"title":"Getting Started with Go","content":"Learn the basics of Go programming","author":{"id":101,"name":"Jane Smith","email":"jane@example.com"},"published":true}}

再例如,给定:

json
2
Draft Post

102
John Doe
john@example.com
false

你的输出应为:

{"success":true,"data":{"id":2,"title":"Draft Post","author":{"id":102,"name":"John Doe","email":"john@example.com"},"published":false}}

注意,内容为空时,JSON 输出中会省略该字段。

再例如,给定:

display
3
Advanced Interfaces
Deep dive into Go interfaces
103
Alice Chen
alice@example.com
true

你的输出应为:

"Advanced Interfaces" by Alice Chen <alice@example.com>
Alice Chen <alice@example.com>

亲手试试

package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// 读取操作类型
	operation, _ := reader.ReadString('\n')
	operation = strings.TrimSpace(operation)

	// 读取文章 ID
	postIDStr, _ := reader.ReadString('\n')
	postID, _ := strconv.Atoi(strings.TrimSpace(postIDStr))

	// 读取标题
	title, _ := reader.ReadString('\n')
	title = strings.TrimSpace(title)

	// 读取内容
	content, _ := reader.ReadString('\n')
	content = strings.TrimSpace(content)

	// 读取作者 ID
	authorIDStr, _ := reader.ReadString('\n')
	authorID, _ := strconv.Atoi(strings.TrimSpace(authorIDStr))

	// 读取作者姓名
	authorName, _ := reader.ReadString('\n')
	authorName = strings.TrimSpace(authorName)

	// 读取作者邮箱
	authorEmail, _ := reader.ReadString('\n')
	authorEmail = strings.TrimSpace(authorEmail)

	// 读取发布状态
	publishedStr, _ := reader.ReadString('\n')
	published := strings.TrimSpace(publishedStr) == "true"

	// TODO: 用读取的值创建 Author 结构体

	// TODO: 用读取的值和 Author 创建 Post 结构体

	// TODO: 处理操作类型
	// 如果 operation 是 "json":
	//   - 创建一个 APIResponse,将 Success 设为 true,并将 Post 设为 Data
	//   - 使用 json.Marshal 转换为 JSON
	//   - 打印 JSON 字符串
	// 如果 operation 是 "display":
	//   - 使用 Post 的 String 方法打印 Post
	//   - 在新的一行打印 Author

	// 用于使用变量的占位代码(实现时删除)
	_ = postID
	_ = title
	_ = content
	_ = authorID
	_ = authorName
	_ = authorEmail
	_ = published
	_ = operation
	_ = json.Marshal
	fmt.Println("TODO: Implement the solution")
}

面向对象编程中的所有课

自己练习: Go 在线编译器