RESTful API на Golang, фреймворке Gin и СУБД РЕД База Данных
Пример демонстрирует реализацию простейшего RESTful API, работающего с БД, на языке программирования Go (Golang) с использованием фреймворка Gin и стандартного пакета database/sql для работы с базами данных.
Подробнее вы можете посмотреть следующие ссылки:
- https://go.dev/doc/database/
- https://go.dev/doc/tutorial/database-access
- https://go.dev/doc/tutorial/web-service-gin
Пример включает в себя:
- Подготовка среды разработки.
- Проектирование API.
- Создание проекта.
- Инициализация БД.
- Подключение к БД.
- Получение всех альбомов.
- Добавление альбома.
Какие инструменты и технологии используются?
- Язык программирования: Go (Golang).
- Веб-фреймворк Gin.
- Пакет для работы с базой данных:
database/sql. - СУБД РЕД База Данных.
- Драйвер для РЕД Базы Данных.
- Операционная система РЕД ОС.
- Редактор VS Code для написания программы.
Подготовка среды разработки
Установка GoLang
- Выполните в терминале команду для установки golang:
sudo dnf install golang
- Проверьте успешность установки командой:
go version
Если установка прошла успешно, команда выведет версию компилятора. В данном случае установлен Go версии 1.22.

- Установите инструменты Go:
sudo go install -v golang.org/x/tools/gopls@latest
- Установите отладчик для Go:
go install github.com/go-delve/delve/cmd/dlv@latest
Установка и настройка VS Code для работы на языке Go
- Добавим репозиторий:
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo sh -c 'echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/VS Code\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/VS Code.repo'
- Обновим список пакетов:
sudo dnf check-update
- Теперь можно установить VS Code:
sudo dnf install code
- Запустить VS Code можно командой:
code
- Перейдите во вкладку Extensions, в поиске введите Go и установите дополнение.

Установка RedDatabase
Установка РЕД Базы Данных подробно рассмотрена в:
- Руководство администратора в документации;
- Видео-курсе по администрированию БД.
Проектирование API
В примере мы разработаем RESTful API, который предоставляет доступ к магазину по продаже винтажных записей на виниле. Так что нужно будет предоставить конечные точки, через которые клиент может получить и добавить альбомы для пользователей.
Разработка API обычно начинается с разработки конечных точек. Важно, чтобы точки можно было легко понять.
В в этом уроке мы создадим следующие точки:
/albums
GET– Получить список альбомов в виде JSON.POST– Добавить новый альбом из данных в виде JSON, полученных в запросе.
Создание проекта
- Для начала нужно создать папку нашего проекта (он будет находиться в домашней директории).
mkdir ~/rdb_go
- Откроем ее при помощи
VS Code.
code ~/rdb_go
- Инициализируем модуль Go
go mod init rdb_go
- В папке проекта создадим файл
main.goсо следующим содержимым:
package main
import "fmt"
func main() {
fmt.Println("Hello, Go!")
}
- Настроим сборку проекта.
Для этого в пункте меню выберите Терминал / Настроить задачу сборки по умолчанию.... После этого в дереве проекта появится папка .vscode, а в ней файл tasks.json с таким содержимым.
{
"version": "2.0.0",
"tasks": [
{
"type": "go",
"label": "go: build package",
"command": "build",
"args": [
"${fileDirname}"
],
"problemMatcher": [
"$go"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "cd /home/roman/rdb_go; go build ${fileDirname}"
}
]
}}
-
Теперь для сборки программы нажмите комбинацию клавиш
Ctrl + Shift + Bили в пункте менюТерминал/Запустить задачу сборки.... -
После успешной сборки проекта в папке появится исполняемый файл
go_hw. Чтобы его запустить, нажмитеF5.
Инициализация БД
Теперь создадим папку, в которой будут храниться базы данных, и выдадим ей права доступа, чтобы сервер СУБД имел доступ к файлам БД.
Для версии РЕД База Данных не выше 3 версии или для Firebird:
mkdir /db
sudo chown firebird: /db
Для версии РЕД База Данных 5 и выше.
mkdir /db
sudo chown reddatabase: /db
Теперь, используя РЕД Эксперт, создайте в каталоге /db новую БД recordings.fdb. Полный путь к БД будет /db/recordings.fdb. В этой БД создайте таблицу ALBUM и добавьте в неё несколько записей, согласно скрипту.
RECREATE TABLE ALBUM (
ID INT GENERATED ALWAYS AS IDENTITY NOT NULL PRIMARY KEY,
TITLE VARCHAR(128) NOT NULL,
ARTIST VARCHAR(255) NOT NULL,
PRICE DECIMAL(5,2) NOT NULL
);
INSERT INTO ALBUM (TITLE, ARTIST, PRICE) VALUES ('Blue Train', 'John Coltrane', 56.99);
INSERT INTO ALBUM (TITLE, ARTIST, PRICE) VALUES ('Giant Steps', 'John Coltrane', 63.99);
INSERT INTO ALBUM (TITLE, ARTIST, PRICE) VALUES ('Jeru', 'Gerry Mulligan', 17.99);
INSERT INTO ALBUM (TITLE, ARTIST, PRICE) VALUES ('Sarah Vaughan', 'Sarah Vaughan', 34.98);
Подключение к БД
Добавьте импорт библиотеки для работы с РЕД База Данных в main.go. Теперь секция import должна выглядеть так.
import (
"database/sql"
"fmt"
"log"
_ "github.com/nakagami/firebirdsql"
)
Чтобы установить ее для сборки нашего проекта, в каталоге с нашей программой (~/rdb_go) выполните:
go get .
Эта команда автоматически загрузит все необходимые библиотеки и подключит все зависимости. Далее, при подключении новых зависимостей, эту команду нужно будет повторять. Сразу все зависимости прописать не получится, так как неиспользуемые библиотеки считаются ошибкой. Обратите внимание, что пакет github.com/nakagami/firebirdsql импортируется с подчеркиванием _, что заставляет компилятор вызвать инициализацию пакета, несмотря на то что явно его содержимое нигде не используется. Оно будет использоваться объектами пакета database/sql.
Теперь напишем код для доступа к нашей БД. Для этого будем использовать глобальный указатель на структуру sql.DB.
В модуле main.go объявите глобальную переменную db и перепишите функцию main как указано ниже.
var db *sql.DB
func main() {
// Строка подключения
connStr := "sysdba:masterkey@localhost/db/recordings.fdb"
// Подключение к базе данных
var err error
db, err = sql.Open("firebirdsql", connStr)
if err != nil {
log.Fatalf("Ошибка подключения к базе данных: %v", err)
}
defer db.Close()
// Проверка соединения
if err := db.Ping(); err != nil {
log.Fatalf("Не удалось подключиться к базе данных: %v", err)
}
fmt.Print("Подключен")
}
db -- это глобальная (для упрощения примера) переменная для работы с базой данных. В реальных проектах избегайте использования глобальных переменных, а передавайте необходимые значения как аргументы функции при вызовах.
connStr -- строковая переменная для хранения строки подключения к БД. В строке подключения указан пользователь (sysdba), пароль (masterkey), адрес сервера (localhost) и путь к файлу БД на этом сервере (/db/recordings.fdb). Еще раз обратите внимание, что с файлом работает сервер СУБД на том компьютере, где он запущен.
sql.Open -- открывает БД и инициализирует переменную db. В случае возникновения ошибки она будет записана в переменную err. Если ошибка возникла, для облегчения диагностики мы выводим ее с помощью log. При этом метод Fatalf выводит форматированное сообщение и немедленно завершает работу программы. В реальных проектах ошибку вероятнее всего необходимо будет обработать и продолжить работу программы.
sql.Ping -- проверяет соединение. В зависимости от драйвера, sql.Open может не установить соединение с сервером сразу же, а лишь при первом обращении. sql.Ping используется, чтобы выполнить простейший запрос и убедиться, что соединение действительно установлено. Обработка ошибок осуществляется аналогичным образом.
В завершение функции выводим сообщение об успешности подключения.
Получение всех альбомов
Теперь напишем функцию, которая будет запрашивать все записи таблицы ALBUM, записывать их в массив структур и возвращать в качестве результата.
В файле main.go опишем структуру для хранения записей об альбомах.
// Album представляет структуру записи в таблице ALBUM
type Album struct {
ID string `json:"id"`
Title string `json:"title"`
Artist string `json:"artist"`
Price float64 `json:"price"`
}
Тэги в этой структуре, такие как json:"artist" определяют имена полей при сериализации или десериализации структуры JSON.
После функции main вставим описание новой функции.
func queryAlbums() ([]Album, error) {
var albums []Album
// SQL-запрос для поиска альбомов
query := "SELECT ID, TITLE, ARTIST, PRICE FROM ALBUM"
rows, err := db.Query(query)
if err != nil {
return nil, fmt.Errorf("ошибка getAlbums: %v", err)
}
defer rows.Close()
// Обработка результата
for rows.Next() {
var alb Album
if err := rows.Scan(&alb.ID, &alb.Title, &alb.Artist, &alb.Price); err != nil {
return nil, fmt.Errorf("ошибка getAlbums: %v", err)
}
albums = append(albums, alb)
}
// Проверка ошибок при обработке строк
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("ошибка getAlbums: %v", err)
}
return albums, nil
}
Функция queryAlbums принимает параметр db *sql.DB -- подключение к БД, которое используется для выполнения запроса.
Результатом функции является массив записей Album и код ошибки.
Для хранения результата функции объявляем переменную albums.
db.Query используется для выполнения запроса (первый параметр). Параметры запроса могут быть указаны через запятую как второй и последующие параметры.
defer rows.Close() гарантирует, что ресурсы, связанные с результатами запроса, будут освобождены после выхода из функции. Цикл для обработки строк rows.Next() перемещается по каждой строке результата. Для каждой строки создаётся новая переменная типа Album (alb), в которую записываются данные из столбцов.
rows.Scan считывает данные столбцов текущей строки и записывает их в поля структуры alb.
Проверить работоспособность кода достаточно просто. Добавьте печать результата этой функции последней строкой функции main.
func main() {
...
fmt.Print("Подключен")
fmt.Print(queryAlbums())
}
При выполнении будет выдан следующий результат
Подключен[{1 Blue Train John Coltrane 56.99} {2 Giant Steps John Coltrane 63.99} {3 Jeru Gerry Mulligan 17.99} {4 Sarah Vaughan Sarah Vaughan 34.98}] <nil>
После объявления структуры Album добавьте функцию, которая будет записывать массив записей Album в JSON представление для ответа HTTP запроса GET.
// getAlbums responds with the list of all albums as JSON.
func getAlbums(c *gin.Context) {
albums, _ := queryAlbums()
c.IndentedJSON(http.StatusOK, albums)
}
Эта функция принимает в качестве параметра gin.Context. Это наиболее важная часть фреймворка Gin. Она хранит детали запроса, проверяет целостность и сериализует JSON и т.д.
IndentedJSON сериализует структуру в JSON и добавляет ее в ответ запроса. Первый параметр функции — это код статуса HTTP, который будет отправлен клиенту. Здесь мы отправляем StatusOK, чтобы отправить статус 200 OK.
Теперь давайте изменим последние строки кода функции main, так, чтобы вместо печати результата вызова queryAlbums, запускать веб-сервер и регистрировать обработчик вызова GET /albums (getAlbums).
Теперь завершение функции main должно выглядеть следующий образом:
func main() {
...
fmt.Print("Подключен")
router := gin.Default()
router.GET("/albums", getAlbums)
router.Run("localhost:8080")
}
Здесь инициализируется маршрутизатор Gin и регистрируется обработчик HTTP GET для пути /albums с нашей функцией getAlbums.
В завершение запускается веб-сервер, слушающий сетевой порт 8080.
Не забудем импортировать вновь задействованные библиотеки.
import (
"database/sql"
"fmt"
"log"
"net/http"
"github.com/gin-gonic/gin"
_ "github.com/nakagami/firebirdsql"
)
и установить их.
go get .
Запустим наше приложение и обратимся к веб-серверу в командной строке.
curl http://localhost:8080/albums
Результатом работы команды будет:
[
{
"ID": 1,
"Title": "Blue Train",
"Artist": "John Coltrane",
"Price": 56.99
},
{
"ID": 2,
"Title": "Giant Steps",
"Artist": "John Coltrane",
"Price": 63.99
},
{
"ID": 3,
"Title": "Jeru",
"Artist": "Gerry Mulligan",
"Price": 17.99
},
{
"ID": 4,
"Title": "Sarah Vaughan",
"Artist": "Sarah Vaughan",
"Price": 34.98
}
]
Для более красивого вывода можно использовать различные средства фронтенд разработки, но это выходит за рамки данной инструкции.
Добавление альбома
Теперь давайте добавим функцию для вставки записи в нашу БД.
Для выполнения запросов, не возвращающих данные, используется метод Exec. Сразу после функции queryAlbums добавим нашу новую функцию.
// addAlbum добавляет запись в БД
func addAlbum(alb Album) (error) {
_, err := db.Exec("INSERT INTO album (title, artist, price) VALUES (?, ?, ?)", alb.Title, alb.Artist, alb.Price)
if err != nil {
return fmt.Errorf("ошибка addAlbum: %v", err)
}
return nil
}
db.Exec -- выполняет SQL-запрос для добавления записи в таблицу ALBUM. При этом ID мы не передаем, потому что это первичный ключ, и он сгенерируется автоматически.
Теперь давайте добавим вызов этой функции в метод POST /albums.
Для этого напишем обработчик HTTP-запроса.
// postAlbums добавляет в БД запись на основе JSON-запроса.
func postAlbums(c *gin.Context) {
var newAlbum Album
if err := c.BindJSON(&newAlbum); err != nil {
return
}
addAlbum(newAlbum)
c.IndentedJSON(http.StatusCreated, newAlbum)
}
BindJSON связывает запрос с полями переменной newAlbum. Далее вызывается наша функция addAlbum для сохранения полученных данных в БД и в HTTP-ответ добавляется статус 201 вместе с JSON-представлением только что вставленной записи.
Добавим регистрацию нового обработчика в функции main.
func main () {
...
router := gin.Default()
router.GET("/albums", getAlbums)
router.POST("/albums", postAlbums)
router.Run("localhost:8080")
}
Чтобы проверить, снова используем утилиту curl и выполним команду
curl http://localhost:8080/albums --include --header "Content-Type: application/json" --request "POST" --data '{"id": "0","title": "he Modern Sound of Betty Carter","artist": "Betty Carter","price": 299.99}'
Её вывод должен быть следующим.
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Date: Sun, 27 Apr 2025 20:39:06 GMT
Content-Length: 116
{
"id": "0",
"title": "The Modern Sound of Betty Carter",
"artist": "Betty Carter",
"price": 299.99
}
Последующий вызов
curl http://localhost:8080/albums
должен уже показать наличие только что вставленной записи
[
{
"id": "1",
"title": "Blue Train",
"artist": "John Coltrane",
"price": 56.99
},
{
"id": "2",
"title": "Giant Steps",
"artist": "John Coltrane",
"price": 63.99
},
{
"id": "3",
"title": "Jeru",
"artist": "Gerry Mulligan",
"price": 17.99
},
{
"id": "4",
"title": "Sarah Vaughan",
"artist": "Sarah Vaughan",
"price": 34.98
},
{
"id": "5",
"title": "The Modern Sound of Betty Carter",
"artist": "Betty Carter",
"price": 299.99
}
]
Заключение
Поздравляем! Вы завершили реализацию простого RESTful API на языке Go с использованием фреймворка Gin, работающего с СУБД РЕД База Данных.
Дата последнего изменения: 14.09.2026
Если вы нашли ошибку, пожалуйста, выделите текст и нажмите Ctrl+Enter.