Перейти к содержимому
ГоМастер

Поиск по урокам

Найдите урок, курс, термин или раздел

Урок 1 из 25 ~15 мин +50 XP

Знакомство с Echo: минимализм, который работает

Echo — веб-фреймворк для Go, который делает ставку на минимализм: роутер, цепочка middleware и честная обработка ошибок через return — и всё. Если вы выбираете между Gin и Echo и не понимаете, зачем существует второй, этот урок для вас: разберём историю проекта, философию API, сравнение с конкурентами и напишем первый код.

Содержание урока · 11 разделов

Типовая задача: нужен HTTP API на Go — пять-шесть эндпоинтов, JSON на входе и выходе, логи, защита от паник. На чистом net/http это делается, и с версии 1.22 у стандартной библиотеки даже появился приличный роутер с методами и wildcards. Но JSON-тело запроса вы всё ещё читаете декодером вручную, ответы собираете по заголовкам руками, а логирование и восстановление после паник — это свои обёртки. К третьему обработчику начинаешь писать один и тот же каркас снова и снова. Echo — тот каркас, вынесенный в библиотеку: маршрутизация, middleware, привязка данных и обработка ошибок собраны в одном пакете github.com/labstack/echo/v4. Его теглай из readme — «high performance, extensible, minimalist» — не маркетинг, а честное описание объёма: в ядре немного кода, и почти любую его часть можно заменить на свою реализацию.

Что такое Echo: короткая история#

Echo — один из старейших живых веб-фреймворков Go: первые коммиты в репозитории labstack/echo датируются 2012 годом, то есть он старше большинства библиотек, которые вы встретите в этой экосистеме. Автор проекта — Ричард Шнайдер (ник vishr), вокруг которого со временем выросла организация Labstack. Настоящая веха — версия 4, вышедшая в конце 2018-го: с ней появился модульный путь github.com/labstack/echo/v4, и с тех пор API живёт в четвёртой мажорной ветке без ломающих изменений. Для сравнения: Gin стартовал в 2014-м, Fiber — в конце 2019-го. Возраст здесь значит не «древность», а предсказуемость: вопросы со Stack Overflow, статьи и примеры из туториалов семилетней давности почти без правок работают на сегодняшнем Echo — редкое свойство для веб-библиотеки, за которое обычно платят революциями при смене мажора.

Что Echo даёт из коробки#

  • Роутер на radix-дереве: сопоставление запроса с маршрутом без аллокаций памяти; статические пути, параметры :id, wildcard *
  • echo.Context — интерфейс с готовыми хелперами: c.JSON, c.Bind, c.Param, c.QueryParam
  • Цепочка middleware: Logger и Recover идут в комплекте, свой middleware — одна функция
  • Центральная обработка ошибок: обработчик возвращает error, фреймворк превращает его в HTTP-статус
  • Пачка встроенных middleware: RequestID, Timeout, Gzip, CORS, CSRF, RateLimiter, Secure
  • Полная совместимость с net/http: стандартные middleware, httptest и прокси работают как есть

Hello world на Echo — присмотритесь, каким коротким он будет

GO
package main

import (
        "net/http"

        "github.com/labstack/echo/v4"
)

func main() {
        e := echo.New()

        e.GET("/ping", func(c echo.Context) error {
                return c.JSON(http.StatusOK, map[string]string{"message": "pong"})
        })

        e.Logger.Fatal(e.Start(":8080"))
}

Классический ping-pong в духе readme Echo. echo.New() создаёт движок; e.GET регистрирует маршрут; обработчик получает echo.Context и обязан вернуть error — c.JSON пишет ответ и возвращает ошибку записи, если она случилась; e.Logger.Fatal(e.Start(...)) поднимает сервер и гасит процесс, если запуститься не удалось. Каждую строку разберём по слогам в следующем уроке — здесь цель просто увидеть объём.

Обработчики возвращают ошибку — главная идея Echo#

Вот ключевая отличительная черта, ради которой стоит читать дальше: сигнатура обработчика — func(c echo.Context) error. В Gin на каждую ошибку вы пишете c.JSON(http.StatusBadRequest, ...) прямо в теле обработчика; в Echo ошибка — это возвращаемое значение. Вернули echo.NewHTTPError(http.StatusBadRequest, "некорректный id") — фреймворк сам превратит её в ответ со статусом 400 и JSON-телом. Вернули обычную ошибку — получите 500 и запись в логе. Вся конвертация живёт в одном месте, HTTPErrorHandler, и его можно заменить своим (детально — в уроке про HTTPError). Это идиоматичнее для Go, где ошибки — часть сигнатуры функций, и заметно сокращает рутину if err != nil в обработчиках. Мне этот стиль нравится больше, чем ручные ответы Gin; но честности ради — на маленьком API разница косметическая, выбирать фреймворк из-за неё не стоит.

Echo vs Gin vs Fiber: сравнение без маркетинга#

Echo и Gin — два самых зрелых фреймворка на net/http, и на бумаге они близнецы: роутер, middleware, привязка данных, совместимость со стандартной библиотекой. Различия всплывают в деталях. В Echo обработчик возвращает error, в Gin отвечает через контекст без возвращаемого значения. echo.Context в Echo — интерфейс, а не структура: его можно расширить или подменить в тестах без хитростей с встраиванием. Роутер Echo на radix-дереве исторически один из самых быстрых; в свежих бенчмарках Gin и Echo ходят рядом, и сильно разойтись им не даёт сам net/http — узкое место реального сервиса почти всегда база данных, а не роутер. По экосистеме и найму Gin крупнее, и это легальный аргумент. Мой водораздел: новый проект, где хочется аккуратного API и централизованных ошибок, — беру Echo; команда с готовым Gin-кодом — не переезжает, миграция ничего не даст. Fiber из этой тройки стоит особняком: он на fasthttp, без полной совместимости с net/http, и его сильные стороны — скорость на простых запросах и Express-привычки для выходцев из Node.js.

Четыре способа написать HTTP-сервис на Go#

ВариантПод капотомОтличительная чертаКому подходит
net/httpстандартная библиотекас Go 1.22 — паттерны маршрутов, но binding и логи своиутилиты, прототипы, два-три эндпоинта
Ginnet/http + форк httprouterсамая большая экосистема и комьюнититиповой production-бэкенд
Echonet/http, собственный роутеробработчик возвращает error; echo.Context — интерфейсте же задачи плюс любовь к аккуратному API
Fiberfasthttp (не net/http)Express-подобный API, максимум скорости на простых запросахвысокие RPS, миграции с Node.js

Когда Echo — правильный выбор, а когда нет#

Моё правило простое. Берите Echo, когда пишете классический HTTP API на Go, начинаете с чистого листа и хотите, чтобы ошибки шли через return, а не через ручные ответы на каждом шаге. Берите Gin, если в команде уже есть Gin-код или нужные библиотеки — экосистема у него богаче, и переезд ради вкуса никто не оплатит. Не нужны ни тот ни другой, когда это два ручки health-check внутри существующего сервиса — хватит net/http. А если ваши сервисы говорят друг с другом по жёстким контрактам, посмотрите сначала на gRPC: там HTTP+JSON — лишний слой сериализации. Цена ошибки небольшая: и Gin, и Echo построены на net/http, миграция между ними для среднего API — день-два работы. Хуже выбрать fasthttp-стек без понимания, зачем он вам: вот там несовместимость с экосистемой уже реальна, а не теоретична.

Экосистема: middleware, JWT и метрики#

Ядро Echo компактно, и часть функциональности сознательно вынесена в соседние репозитории. JWT-аутентификация живёт в отдельном модуле github.com/labstack/echo-jwt/v4 — в ранних версиях она была встроенным middleware.JWT, а в четвёртой версии её вынесли. Организация Labstack держит репозиторий echo-contrib: сессии, Prometheus-метрики, pprof. Валидация — через популярный go-playground/validator: подключаете его к e.Validator, и c.Validate(input) начинает проверять struct-теги (придёт в уроке про валидацию). Документация — на labstack.com/echo, и она разделена по версиям: примеры для v3 читайте с осторожностью, API между мажорами менялся.

Одна оговорка про формат этого курса: песочница сайта исполняет чистый Go без сети, поэтому Echo-код в уроках не запускается в браузере. Чтобы гонять примеры руками, поставьте локальный Go (пять минут по инструкции базового курса) и сделайте go get для зависимостей — покажем всё в следующем уроке.

Проверка: на чём стоит Echo

На каком HTTP-движке построен Echo?

Проверка: сигнатура обработчика

Какую сигнатуру обязан иметь обработчик маршрута в Echo?

Заполните пропуски в hello world

Восстановите минимальный сервер: имя пакета, организация в пути импорта, конструктор движка, метод ответа и метод запуска.

package import ( "net/http" "github.com//echo/v4" ) func main() { e := echo.() e.GET("/ping", func(c echo.Context) error { return c.(http.StatusOK, map[string]string{"message": "pong"}) }) e.Logger.Fatal(e.(":8080")) }

Соберите ping-сервер из строк

Расставьте строки в правильном порядке — от объявления пакета до запуска.

Строки

Ваша программа

Нажимайте на строки слева, чтобы собрать программу

Карточки: словарь Echo

Термин

Echo

нажмите, чтобы перевернуть
Определение

Веб-фреймворк для Go (проект с 2012 года, организация Labstack): роутер, middleware и хелперы для HTTP API. Теглай — high performance, extensible, minimalist.

1 / 6

Что дальше по курсу#

Во втором уроке поднимем первый сервер: go mod init, echo.New, Logger, Recover и POST-эндпоинт с c.Bind — каждую строку разберём по слогам. В третьем — маршрутизация и параметры: c.Param, c.QueryParam и правило приоритета маршрутов. Дальше binding и валидация, middleware, JWT, тесты и итоговый REST API в финальном уроке. Если Go пока на уровне «читал, но не писал», начните с базового курса: структуры, указатели и ошибки из него понадобятся уже со второго урока. И последнее: тесты, «заполни пропуск» и «собери программу» в каждом уроке дают XP и работают без запуска кода, а примеры копируйте в локальный проект — живые логи настоящего сервера не заменит ни один разбор.

Песочница урока

Редактируйте код и запускайте его прямо здесь — интерпретатор работает в браузере, ничего устанавливать не нужно. За каждый запуск — +2 XP.

Вывод

Запустите код, чтобы увидеть вывод.

Коротко: что запомнить

  • Echo — минималистичный фреймворк на net/http из Labstack; проект старше большинства Go-фреймворков (2012).
  • Обработчик в Echo — func(c echo.Context) error: ошибка возвращается, а не пишется в ответ вручную.
  • echo.Context — интерфейс: контекст можно расширять и подменять в тестах.
  • Echo vs Gin: API близки, разница — в стиле ошибок и интерфейсе контекста; экосистема у Gin больше.
  • Fiber остаётся на fasthttp: быстрый на простых запросах, но без полной совместимости с net/http.
  • JWT вынесен в echo-jwt, метрики и сессии — в echo-contrib; валидация — go-playground/validator.
  • Код курса не запускается в песочнице: нужен локальный Go и go get github.com/labstack/echo/v4.

Домашнее задание

Соберите hello world из урока локально: go mod init demo, затем go get github.com/labstack/echo/v4, запустите и откройте http://localhost:8080/ping. Потом добавьте маршрут /about, который через c.String отвечает коротким текстом о вашем проекте, и перезапустите сервер: убедитесь, что маршруты добавляются прямо в main(), без новых файлов и настроек.

Личные заметкиПусто
Хранятся только в вашем браузере (Echo · Знакомство с Echo: минимализм, который работает)

Вопросы и ответы по уроку

Что такое Echo простыми словами?

Библиотека для Go, которая берёт на себя рутину HTTP-сервиса: маршруты, middleware, чтение JSON и конвертацию ошибок в статус-коды. Вы пишете только функции-обработчики.

Echo или Gin — что выбрать?

Для нового проекта с нуля я беру Echo ради ошибок через return и аккуратного API. Если в команде уже есть Gin-код, переезжать ради вкуса не стоит: экосистема Gin крупнее.

Echo быстрее Gin?

В свежих бенчмарках они идут рядом: оба на net/http, и узкое место обычно база данных, а не роутер. Выбирать между этими двумя по скорости — почти всегда потерянное время.

Термины урока

Ключевые понятия из этого урока — короткие определения в глоссарии. Наведите на термин, чтобы вспомнить, откройте карточку для подробностей и ссылки на практику.

Сравните с альтернативами

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

Следующая ступень учебного пути

GORM25 уроков~14 чпрактика25 уроков уже доступны

GORM: ORM-библиотека для Go

Курс GORM: модели, CRUD, ассоциации, транзакции, хуки, пагинация, оптимизация запросов. 25 уроков с примерами и проектом слоя данных.

  • Подключать БД и настраивать пул соединений
  • Описывать модели и связи: 1:1, 1:N, M:N
  • Писать CRUD и сложные выборки chainable-стилем
  • Контролировать N+1 через Preload