Создайте простой API на Go с помощью Fiber, Postgres и GORM

Согласно Опросу разработчиков StackOverflow и индексу TIOBE, Go (или Golang) в последние годы набирает обороты, особенно среди бэкэнд-разработчиков и команд DevOps, работающих над автоматизацией инфраструктуры. Этого достаточно, чтобы написать простое руководство, чтобы познакомить вас с Go.

Этому стоит научиться, поэтому в этой статье я хочу показать вам краткое руководство о том, как разработать масштабируемый, но простой CRUD API в Go с использованием Fiber и GORM. Для простоты мы не будем использовать Docker.

Что такое клетчатка?

Fiber — это веб-фреймворк, вдохновленный Express, построенный на основе Fasthttp, самого быстрого HTTP-движка для Go. Разработан для упрощения быстрой разработки с нулевым выделением памяти и производительностью. Так что, если вы имеете опыт работы с NodeJS, Fibe может вам подойти.

Что будем строить?

Проект будет очень классическим. Мы собираемся создать простой API Book на основе CRUD. Таким образом, у нас будут разные конечные точки для создания, чтения, обновления и удаления.

Предпосылки

Вы должны иметь базовые знания о Go. Я выберу Visual Studio Code в качестве редактора кода. Вы можете использовать все, что вы предпочитаете. Но имейте в виду, что в этой статье вы встретите команду code . один раз. Это специальная команда VSCode (Visual Studio Code), которая открывает текущий каталог в VSCode.

Вам также необходимо установить эти:

  • Установите Go на локальную машину
  • Установите Postgres на свой локальный компьютер

Любая последняя версия обоих в порядке. Однако моя версия Go — 1.18, а PostgreSQL — версия 14.

Создать базу данных

Во-первых, нам нужно создать базу данных Postgres. Я знаю, все решают это по-своему, некоторые люди используют графический интерфейс, но мы собираемся использовать наш терминал. Опять же, на вашем компьютере должен быть установлен Postgres. Если у вас установлен Postgres, следующие четыре команды будут выполняться на компьютерах с Linux, Mac и Windows.

$ psql postgres
$ CREATE DATABASE go_fiber_api;
$ \l
$ \q
  • psql postgres открыть psql интерфейс командной строки с пользователем postgres
  • CREATE DATABASE go_fiber_api; создание необходимой нам базы данных
  • \l перечислить все базы данных
  • \q Выход из командной строки

Мой терминал будет выглядеть так после того, как мы успешно выполним все четыре команды. Как мы видим, база данных go_fiber_api создана.

Настройка проекта

Прежде всего, мы собираемся инициировать наш проект и установить необходимые нам модули.

Внимание! Замените YOUR_USERNAME своим именем пользователя Github.

$ mkdir go-fiber-api
$ cd go-fiber-api
$ code .
$ go mod init github.com/YOUR_USERNAME/go-fiber-api

Теперь давайте установим Fiber, GORM и Viper. Мы используем Viper для управления переменными среды.

$ go get github.com/spf13/viper
$ go get github.com/gofiber/fiber/v2
$ go get gorm.io/gorm
$ go get gorm.io/driver/postgres

Давайте продолжим с окончательной структурой проекта.

$ mkdir -p cmd pkg/books pkg/common/db pkg/common/config/envs pkg/common/models

Кроме того, давайте добавим несколько файлов.

$ touch Makefile cmd/main.go pkg/books/add_book.go pkg/books/controller.go pkg/books/delete_book.go pkg/books/get_book.go pkg/books/get_books.go pkg/books/update_book.go pkg/common/db/db.go pkg/common/config/envs/.env pkg/common/models/book.go pkg/common/config/config.go

Итак, после создания нашего проекта файловая структура должна выглядеть так:

Теперь пришло время кодировать.

Переменные среды

Во-первых, нам нужно добавить некоторые переменные среды, в которых мы храним порт приложения, который мы собираемся прослушивать, и URL-адрес базы данных. Имейте в виду, чтобы заменить DB_USER, DB_PASSWORD, DB_HOST и DB_PORT данными вашей базы данных.

Давайте добавим код в pkg/common/envs/.env

Например, как это будет выглядеть на моей локальной машине:

Конфигурация

Давайте добавим код в pkg/common/config/config.go

Книжные модели

Здесь мы собираемся создать модель/объект Book. gorm.Model добавит для нас такие свойства, как ID, CreatedAt, UpdatedAt и DeletedAt.

Кроме того, мы добавляем 3 строковых свойства. Тег json в конце дает GORM информацию об именах каждого столбца в нашей базе данных Postgres.

Давайте добавим код в pkg/common/models/book.go

Инициализация базы данных

Модель книги готова. Теперь мы настраиваем GORM и автоматически переносим только что созданную модель. Эта функция AutoMigrate создаст для нас таблицу books, как только мы запустим это приложение.

Давайте добавим код в pkg/common/db/db.go

Основной файл

Это наш загрузочный файл. Мы собираемся сделать здесь многое.

  • Инициализация Viper для обработки переменных среды
  • Инициализация базы данных на основе GORM
  • Добавление простого маршрута «/»
  • Запуск приложения

Позже мы снова изменим этот файл.

Давайте добавим код в cmd/main.go

Теперь давайте протестируем текущую версию нашего проекта. Обычно приложение будет работать в режиме отладки, поэтому мы получим некоторые предупреждения, просто игнорируйте их.

$ go run cmd/main

Вывод внутри консоли. Самая последняя строчка важна.

Заходим на http://localhost:3000

Большой. Мы видим порт нашего приложения. Это означает, что все работает так, как ожидалось.

Обработчики книг

Отлично, все работает. Мы собираемся заменить этот вывод, так что не волнуйтесь. Теперь давайте добавим несколько обработчиков для нашего Book API.

Контроллер

Обработчики книг/маршруты будут основаны на так называемых приемниках указателей, для этого мы определим его структуру. Эта структура получит информацию из базы данных позже, поэтому всякий раз, когда мы вызываем обработчик книги/маршрут, у нас будет доступ к GORM. Позже мы снова изменим этот файл.

Давайте добавим код в pkg/books/controller.go

Добавить обработчик книг

Итак, этот файл очень интересен. После импорта мы определяем структуру тела запроса. В строке 16 вы можете увидеть приемник указателя, который мы определили на предыдущем шаге. В строке 31 вы можете видеть, что мы используем этот приемник указателя, имя переменной которого просто h.

Все остальное довольно просто. Мы получаем тело запроса, объявляем новую переменную книги, объединяем тело запроса с этой переменной книги и создаем новую запись в базе данных. Затем мы создаем ответ с информацией о книге.

Давайте добавим код в pkg/books/add_book.go

Получить обработчик книг

По этому маршруту мы собираемся вернуть все книги из нашей базы данных. Сейчас это работает довольно быстро, но как только у вас будет больше данных для обработки, лучше используйте подход с разбиением на страницы.

Давайте добавим код в pkg/books/get_books.go

Получить обработчик книг

Здесь мы просто отвечаем только одной книгой на основе идентификатора, который мы получаем из параметра.

Давайте добавим код в pkg/books/get_book.go

Обновить обработчик книги

Если мы добавим книгу, у нас также должна быть возможность обновить созданные книги. Этот маршрут похож на маршрут AddBook, который мы закодировали ранее.

Давайте добавим код в pkg/books/update_book.go

Удалить обработчик книги

Это наш последний маршрут в этой статье. Здесь мы удаляем книгу на основе ее идентификатора, но только в том случае, если нужная запись существует в базе данных. Мы отвечаем только кодом состояния HTTP.

Давайте добавим код в pkg/books/delete_book.go

Контролер (снова)

Маршруты сделаны. Теперь нам нужно еще раз изменить файл контроллера. На этот раз мы создаем функцию с именем RegisterRoutes, она сама собой объясняет, что она делает, верно?

Вы помните указатель приемника? Здесь мы получаем указатель получателя для наших маршрутов/обработчиков.

Давайте изменим файлpkg/books/controller.go с:

to:

Основной файл (снова)

Кроме того, нам нужно еще раз изменить наш основной файл. Раньше мы просто инициализировали базу данных. Но на этот раз мы получаем его возврат и регистрируем наши маршруты/обработчики.

Давайте изменим файл cmd/main.go с:

to:

Makefile

Это необязательно. Здесь мы можем установить некоторые скрипты для упрощения команд. Например, мы определяем сценарий server для запуска приложения. Поэтому вместо запуска приложения go run cmd/main мы запускаем его make server. Этот пример не очень хорош, так как реальная команда довольно короткая, но представьте, что вам придется иметь дело с более длинными командами.

Давайте добавим код в Makefile внутри корневого каталога.

Запустить приложение

Все сделано! Кодирования больше нет. Теперь давайте запустим приложение.

$ make server

or

$ go run cmd/main.go

Вывод должен выглядеть следующим образом. Помимо предупреждений, мы видим, что наши маршруты утряслись и приложение работает на порту 3000.

Тестирование конечных точек

Теперь мы можем протестировать два только что созданных маршрута. Мы можем протестировать это с помощью таких программ, как Postman, Insomnia, или просто запустить команды CURL.

POST: Добавить новую книгу

$ curl --request POST \
  --url http://localhost:3000/books \
  --header 'Content-Type: application/json' \
  --data '{
    "title": "Book A",
    "author": "Kevin Vogel",
    "description": "Some cool description"
  }'

ПОЛУЧИТЬ: Получить все книги

Не забывайте, что вы также можете запускать команды GET в своем браузере.

$ curl --request GET --url http://localhost:3000/books

ПОЛУЧИТЬ: Получить книгу по ID

$ curl --request GET --url http://localhost:3000/books/1

PUT: обновить книгу по идентификатору

$ curl --request PUT \
  --url http://localhost:3000/books/1 \
  --header 'Content-Type: application/json' \
  --data '{
 "title": "Updated Book Name",
 "author": "Kevin Vogel",
 "description": "Updated description"
}'

УДАЛИТЬ: Удалить книгу по идентификатору

$ curl --request DELETE --url http://localhost:3000/books/1

Мы сделали! Большой. Не забывайте, что я выложил этот проект на Github.

Спасибо, что прочитали эту статью о том, как создать масштабируемый, но простой API в Go с помощью Fiber. Надеюсь, вы смогли узнать что-то новое. Дайте мне знать, если у вас есть вопросы.

Ваше здоровье!