Повторение: модели REST API
Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy — урок 78 из 107.
Задание
ЛегкоДавайте создадим систему моделей 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 автора, имя автора, email автора и статус публикации (trueилиfalse).Для
json: Создайте APIResponse сSuccess: trueи Post в качестве данных (оставьте Message пустым). Преобразуйте в JSON и выведите его.Для
display: Создайте Post и выведите его, используя метод String, затем выведите Author отдельно на новой строке.
Будут предоставлены следующие входные данные:
- Строка 1: Тип операции (
jsonилиdisplay) - Строка 2: ID поста
- Строка 3: Заголовок
- Строка 4: Содержимое (может быть пустым)
- Строка 5: ID автора
- Строка 6: Имя автора
- Строка 7: Email автора
- Строка 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}}Обратите внимание, как пустое поле content опускается в выводе 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)
// Считать email автора
authorEmail, _ := reader.ReadString('\n')
authorEmail = strings.TrimSpace(authorEmail)
// Считать статус публикации
publishedStr, _ := reader.ReadString('\n')
published := strings.TrimSpace(publishedStr) == "true"
// TODO: Создать структуру Author с прочитанными значениями
// TODO: Создать структуру Post с прочитанными значениями и Author
// TODO: Обработать тип операции
// Если operation равно "json":
// - Создать APIResponse с Success: true и Post в качестве Data
// - Преобразовать в JSON, используя json.Marshal
// - Вывести JSON-строку
// Если operation равно "display":
// - Вывести Post, используя его метод String
// - Вывести Author на новой строке
// Заполнитель для использования переменных (удалить при реализации)
_ = postID
_ = title
_ = content
_ = authorID
_ = authorName
_ = authorEmail
_ = published
_ = operation
_ = json.Marshal
fmt.Println("TODO: Implement the solution")
}
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП в Go
Внешние файлыРабочее пространство и модули GoПакеты и импортыЭкспортируемые и неэкспортируемые именаВведение в ООП в GoСтруктуры как классыОпределение методов структурПолучатели-указатели и получатели-значенияИнициализация структурФункции-конструкторыИтоги — Простой калькулятор4Интерфейсы
Введение в интерфейсыНеявная реализацияИнтерфейс как контрактПустой интерфейс (any)Утверждение типаПереключатель типовКомпозиция интерфейсовИнтерфейсы Stringer и ErrorПовторение: Калькулятор фигур7Инкапсуляция
Экспортируемые и неэкспортируемые поляИнкапсуляция на уровне пакетовГеттеры и сеттерыСокрытие информации в GoИтоги — Записи о студентах10Обобщения (Generics) (Go 1.18+)
Введение в GenericsПараметры типовОграничения типовОбобщенные структурыОбходной путь для обобщенных методовИтоги — Обобщенная коллекция13Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн Abstract FactoryПаттерн ObserverПаттерн Strategy2Глубокое погружение в типы и структуры
Базовые и составные типыОпределение пользовательских типовТеги структурАнонимные структурыВложенные структурыНулевые значения и значения по умолчаниюПовторение — Контактная книга5Композиция вместо наследования
Почему в Go нет наследованияОсновы встраивания структурПродвижение методовВстраивание нескольких структурВстраивание против агрегацииЗатенение встроенных методовИтоги — Иерархия сотрудников8Обработка ошибок и ООП
Интерфейс errorПользовательские типы ошибокОбертывание ошибок (fmt.Errorf)Sentinel-ошибкиerrors.Is() и errors.As()Panic, Defer и RecoverИтоги — Парсер файлов11Стандартная библиотека и ООП
io.Reader и io.Writersort.InterfaceИнтерфейс fmt.Stringerencoding/json со структурамиИнтерфейс http.HandlerПовторение: модели REST API14Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикMiddleware как Декоратор3Указатели и память
Основы указателей в GoУказатели на структурыПередача по значению и по ссылкеФункция new()Сборка мусора в GoПовторение: Конструктор связного списка6Полиморфизм в Go
Полиморфизм через интерфейсыУтиная типизация в GoПравила реализации интерфейсовПолиморфные коллекцииВнедрение зависимостейИтоги — Обработчик платежей9Конкурентность и ООП
Основы горутинКаналы и взаимодействиеБуферизованные и небуферизованные каналыОператор selectsync.Mutex и sync.RWMutexsync.WaitGroupПроектирование потокобезопасных структурПовторение — Worker Pool