Как создать API с помощью Go и QuestDB

QuestDB — это реляционная колоночно-ориентированная база данных, предназначенная для работы с временными рядами и данными о событиях. Она использует SQL с расширениями для временных рядов, чтобы помочь в анализе в реальном времени.

Если вы недостаточно знакомы с QuestDB, вот ссылка для ознакомления.

В этом руководстве мы создадим простой API и внедрим QuestDB в качестве базы данных временных рядов в наш проект. Затем мы будем использовать Gin Framework для работы с HTTP-маршрутами.

Прежде чем мы начнем, я предположу, что вы:

  • На вашей машине установлен Go
  • Понимаете основы языка Go
  • Имеете общее представление о RESTful API

Запуск QuestDB

Во-первых, нам нужно запустить QuestDB на нашем локальном компьютере. Существует несколько способов его установки, вы можете найти здесь. Но для удобства мы будем использовать Docker и последний образ Docker questdb.

Чтобы запустить QuestDB через Docker, выполните следующие действия:

docker run -p 9000:9000 
  -p 9009:9009 
  -p 8812:8812 
  questdb/questdb
Войдите в полноэкранный режим Выйти из полноэкранного режима

В качестве альтернативы пользователи macOS могут использовать Homebrew:

brew install questdb
brew services start questdb
Войти в полноэкранный режим Выйти из полноэкранного режима

После запуска QuestDB веб-консоль доступна на порту 9000, поэтому при переходе на localhost:9000 должен появиться пользовательский интерфейс, который выглядит следующим образом:

Итак, QuestDB готова. Теперь давайте приступим к следующему шагу.

Создание REST API в Go с помощью Gin и Gorm

Начнем с инициализации нового модуля Go для управления зависимостями нашего проекта.

go mod init
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь установим необходимые зависимости

go get -u github.com/joho/godotenv
go get -u gorm.io/gorm
go get -u github.com/gin-gonic/gin
Войти в полноэкранный режим Выйти из полноэкранного режима

После завершения установки папка должна содержать go.mod и go.sum. Оба файла содержат информацию о пакетах, которые мы установили.

Для справки, я опубликовал весь исходный код на своем github. Не стесняйтесь клонировать его.

git clone https://github.com/arifintahu/go-api-questdb
Вход в полноэкранный режим Выход из полноэкранного режима

Настройка базы данных

Давайте начнем с создания подключения к базе данных и моделей.

// models/tracker.go

package models

import (
    "time"
)

type Tracker struct {
    Timestamp time.Time     `gorm:"type:timestamp" json:"timestamp"`
    VehicleId int           `gorm:"type:int" json:"vehicleId"`
    Latitude  float64       `gorm:"type:double" json:"latitude"`
    Longitude float64       `gorm:"type:double" json:"longitude"`
}
Войти в полноэкранный режим Выход из полноэкранного режима

У нас есть модели tracker, которые будут записывать каждое положение автомобилей. Каждый трекер должен иметь метку времени, VehicleId с типом integer, широту и долготу с типом float. Мы должны рассмотреть, доступны ли наши типы в типах QuestDB или нет, как указано здесь.

Далее мы создадим функцию настройки для подключения к нашей базе данных. Мы можем взаимодействовать с базой данных QuestDB, подключаясь к различным конечным точкам сети, таким как Web-консоль, линейный протокол InfluxDB, протокол PostgreSQL Wire Protocol, HTTP REST API.

Мы будем использовать PostgreSQL Wire Protocol, подключившись к порту 8812, потому что мы можем использовать gorm в качестве ORM в golang. Перед этим нам нужно установить gorm driver postgres, потому что мы будем подключать QuestDB с помощью драйвера Postgres.

go get -u gorm.io/driver/postgres
Вход в полноэкранный режим Выход из полноэкранного режима

Затем мы напишем функцию для подключения к базе данных.

// models/setup.go

package models

import (
    "fmt"

    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

var DB *gorm.DB

type DBConfig struct {
    Host string
    User string
    Password string
    Name string
    Port string
}

func (dbConfig *DBConfig) ConnectDatabase() error {
    dsn := fmt.Sprintf(
        "host=%s user=%s password=%s dbname=%s port=%s",
        dbConfig.Host,
        dbConfig.User,
        dbConfig.Password,
        dbConfig.Name,
        dbConfig.Port,
    )

    database, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})

    if err != nil {
        return err
    }

    database.AutoMigrate(&Tracker{})

    DB = database

    return nil
}
Войти в полноэкранный режим Выйти из полноэкранного режима

В setup.go мы также определяем автоматическую миграцию для модели tracker. Поэтому нам не нужно сначала создавать таблицу в нашей базе данных.

Написание контроллеров

Далее мы создадим простые контроллеры, в которых мы сможем создавать и находить трекеры.

// controllers/trackers.go

package controllers

import (
    "go-api-questdb/models"
    "net/http"
    "time"

    "github.com/gin-gonic/gin"
)

type CreateTrackerInput struct {
    VehicleId int    `json:"vehicleId"`
    Latitude  float64 `json:"latitude"`
    Longitude float64 `json:"longitude"`
}

func CreateTracker(c *gin.Context) {
    var input CreateTrackerInput
    if err:= c.ShouldBindJSON(&input); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"data": err.Error()})
        return
    }

    tracker := models.Tracker{
        Timestamp: time.Now().UTC(),
        VehicleId: input.VehicleId,
        Latitude: input.Latitude,
        Longitude: input.Longitude,
    }

    models.DB.Create(&tracker)

    c.JSON(http.StatusOK, gin.H{"data": tracker})
}

func GetTrackers(c *gin.Context) {
    var trackers []models.Tracker
    models.DB.Find(&trackers)

    c.JSON(http.StatusOK, gin.H{"data": trackers})
}
Вход в полноэкранный режим Выход из полноэкранного режима

В контроллере трекеров у нас есть CreateTrackerInput для проверки тела запроса в обработчике CreateTracker, затем мы просто вызываем наш экземпляр DB для выполнения создания строки. У нас также есть обработчик GetTrackers для получения всех строк.

RESTful маршруты

Мы почти у цели!

Осталось создать обработчик маршрута и точку входа в приложение.

// main.go

package main

import (
    "go-api-questdb/controllers"
    "go-api-questdb/models"
    "os"

    "github.com/gin-gonic/gin"
    _ "github.com/joho/godotenv/autoload"
)

func main() {
    r := gin.Default()

    dbConfig := models.DBConfig{
        Host: os.Getenv("DB_HOST"),
        User: os.Getenv("DB_USER"),
        Password: os.Getenv("DB_PASSWORD"),
        Name: os.Getenv("DB_NAME"),
        Port: os.Getenv("DB_PORT"),
    }
    err := dbConfig.ConnectDatabase()

    if err != nil {
        panic(err)
    }

    r.POST("/trackers", controllers.CreateTracker)
    r.GET("/trackers", controllers.GetTrackers)

    r.Run("localhost:3000")
}
Вход в полноэкранный режим Выход из полноэкранного режима

В main.go у нас есть dbConfig для инициализации подключения к базе данных, и мы загружаем учетные данные базы данных в файл .env. Поэтому нам необходимо добавить файл .env в наш проект.

Мы будем использовать пользователя и пароль QuestDB по умолчанию, как указано здесь

// .env

DB_HOST=localhost
DB_USER=admin
DB_PASSWORD=quest
DB_NAME=qdb
DB_PORT=8812
Вход в полноэкранный режим Выйти из полноэкранного режима

Хорошо, давайте запустим API

go run main.go
Вход в полноэкранный режим Выйти из полноэкранного режима


Отлично, наше приложение успешно запущено на localhost:3000 и успешно мигрирует новую таблицу.

Давайте проверим это, отправив запрос POST на localhost:3000/trackers.

curl --request POST 'localhost:3000/trackers' --header 'Content-Type: application/json' --data-raw '{ "vehicleId": 1, "latitude": -7.626923, "longitude": 111.5213978 }'
Вход в полноэкранный режим Выйти из полноэкранного режима

Затем мы получили

{
    "data": {
        "timestamp": "2022-09-09T09:56:01.8970862Z",
        "vehicleId": 1,
        "latitude": -7.626923,
        "longitude": 111.5213978
    }
}
Войти в полноэкранный режим Выход из полноэкранного режима

Проверим еще раз, отправив запрос GET на localhost:3000/trackers и мы получили

{
    "data": [
        {
            "timestamp": "2022-09-09T09:56:01.8970862Z",
            "vehicleId": 1,
            "latitude": -7.626923,
            "longitude": 111.5213978
        }
    ]
}
Вход в полноэкранный режим Выход из полноэкранного режима

Ура, мы успешно создали API с Go и QuestDB 🌟 🌟 🌟 🌟 🌟 🌟 🌟

Оцените статью
devanswers.ru
Добавить комментарий