Розробка бекенду сайту на Go (Echo)

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка бекенду сайту на Go (Echo)
Середня
від 1 тижня до 3 місяців
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Розробка веб-бекенду на Go (Echo)

Echo й Gin вирішують одне завдання, різними підходами. Echo робить акцент на розширюваності: middleware, context, binder—все це інтерфейси, які можна замінити. Gin трішки швидший у бенчмарках, Echo трішки зручніший архітектурно, особливо при написанні middleware. На реальних проектах різниця в продуктивності несуттєва—вузьке місце майже завжди у БД, а не у маршрутизаторі.

Вибирають Echo за: зручний API групування маршрутів, вбудований Validator interface, хорошу підтримку WebSocket й SSE, читаний код middleware.

Ініціалізація й маршрути

package server

import (
    "net/http"

    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
    "github.com/myapp/internal/domain/product"
    custmw "github.com/myapp/internal/middleware"
)

type Server struct {
    echo    *echo.Echo
    product *product.Handler
}

func New(deps Dependencies) *Server {
    e := echo.New()
    e.HideBanner = true
    e.Validator = custmw.NewValidator()

    // Вбудований middleware
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())
    e.Use(middleware.CORS())
    e.Use(middleware.RateLimiter(middleware.NewRateLimiterMemoryStore(100)))

    s := &Server{echo: e, product: product.NewHandler(deps)}
    s.registerRoutes()
    return s
}

func (s *Server) registerRoutes() {
    api := s.echo.Group("/api/v1")

    // Публічні
    authGroup := api.Group("/auth")
    authGroup.POST("/login", s.product.Login)

    // Захищені
    restricted := api.Group("", custmw.JWT())
    restricted.GET("/profile", s.product.Profile)

    // Продукти
    products := api.Group("/products")
    products.GET("", s.product.List)
    products.GET("/:id", s.product.Get)
}

Handler (Контролер)

package product

import (
    "net/http"
    "github.com/labstack/echo/v4"
    "github.com/myapp/internal/domain"
)

type Handler struct {
    service *Service
}

func (h *Handler) List(c echo.Context) error {
    page := c.QueryParamDefault("page", "1")
    limit := c.QueryParamDefault("limit", "20")

    products, total, err := h.service.List(c.Request().Context(), page, limit)
    if err != nil {
        return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
    }

    return c.JSON(http.StatusOK, map[string]interface{}{
        "data":  products,
        "total": total,
    })
}

func (h *Handler) Get(c echo.Context) error {
    id := c.Param("id")

    product, err := h.service.GetByID(c.Request().Context(), id)
    if err != nil {
        if err == domain.ErrNotFound {
            return c.JSON(http.StatusNotFound, map[string]string{"error": "Not found"})
        }
        return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
    }

    return c.JSON(http.StatusOK, product)
}

Service (Бізнес-логіка)

package product

import (
    "context"
    "github.com/myapp/internal/domain"
)

type Service struct {
    repo domain.ProductRepository
}

func (s *Service) List(ctx context.Context, page, limit string) ([]domain.Product, int, error) {
    products, err := s.repo.FindMany(ctx)
    if err != nil {
        return nil, 0, err
    }
    return products, len(products), nil
}

func (s *Service) GetByID(ctx context.Context, id string) (*domain.Product, error) {
    return s.repo.FindByID(ctx, id)
}

Шар бази даних

package repository

import (
    "context"
    "database/sql"
    "github.com/myapp/internal/domain"
)

type ProductRepository struct {
    db *sql.DB
}

func (r *ProductRepository) FindByID(ctx context.Context, id string) (*domain.Product, error) {
    var p domain.Product
    err := r.db.QueryRowContext(
        ctx,
        "SELECT id, name, price, created_at FROM products WHERE id = $1",
        id,
    ).Scan(&p.ID, &p.Name, &p.Price, &p.CreatedAt)

    if err == sql.ErrNoRows {
        return nil, domain.ErrNotFound
    }
    return &p, err
}

Кастомний middleware

package middleware

import (
    "github.com/labstack/echo/v4"
    "github.com/golang-jwt/jwt/v5"
)

func JWT() echo.MiddlewareFunc {
    return func(next echo.HandlerFunc) echo.HandlerFunc {
        return func(c echo.Context) error {
            token := c.Request().Header.Get("Authorization")
            if token == "" {
                return c.JSON(401, map[string]string{"error": "Unauthorized"})
            }

            // Валідуємо token
            _, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
                return []byte("secret"), nil
            })
            if err != nil {
                return c.JSON(401, map[string]string{"error": "Invalid token"})
            }

            return next(c)
        }
    }
}

Таймлайн

Базовий сетап: маршрути, обробники, middleware—1 день. Інтеграція БД, бізнес-логіка—2–3 дні. Повний API з тестами—1 тиждень.

Go/Echo переваги: скомпільований бінарник, одна розгортка, відмінна продуктивність, статична типізація ловить помилки на ранній стадії.