Содержание урока · 11 разделов
- Что такое Echo: короткая история
- Что Echo даёт из коробки
- Обработчики возвращают ошибку — главная идея Echo
- Echo vs Gin vs Fiber: сравнение без маркетинга
- Четыре способа написать HTTP-сервис на Go
- Когда Echo — правильный выбор, а когда нет
- Экосистема: middleware, JWT и метрики
- Что дальше по курсу
- Песочница урока
- Коротко: что запомнить
- Вопросы и ответы
Типовая задача: нужен 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 — присмотритесь, каким коротким он будет
GOpackage 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 и логи свои | утилиты, прототипы, два-три эндпоинта |
| Gin | net/http + форк httprouter | самая большая экосистема и комьюнити | типовой production-бэкенд |
| Echo | net/http, собственный роутер | обработчик возвращает error; echo.Context — интерфейс | те же задачи плюс любовь к аккуратному API |
| Fiber | fasthttp (не 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 для зависимостей — покажем всё в следующем уроке.
С конца 2018 года Echo живёт в ветке v4 без ломающих изменений: обновление обычно сводится к go get -u. Примеры из старых туториалов с /v4-импортом компилируются без правок — для учебных проектов это экономит часы.
Проверка: на чём стоит Echo
На каком HTTP-движке построен Echo?
Проверка: сигнатура обработчика
Какую сигнатуру обязан иметь обработчик маршрута в Echo?
Заполните пропуски в hello world
Восстановите минимальный сервер: имя пакета, организация в пути импорта, конструктор движка, метод ответа и метод запуска.
Соберите ping-сервер из строк
Расставьте строки в правильном порядке — от объявления пакета до запуска.
Строки
Ваша программа
Нажимайте на строки слева, чтобы собрать программу
Карточки: словарь Echo
Что дальше по курсу#
Во втором уроке поднимем первый сервер: 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 простыми словами?
Библиотека для Go, которая берёт на себя рутину HTTP-сервиса: маршруты, middleware, чтение JSON и конвертацию ошибок в статус-коды. Вы пишете только функции-обработчики.
Echo или Gin — что выбрать?
Для нового проекта с нуля я беру Echo ради ошибок через return и аккуратного API. Если в команде уже есть Gin-код, переезжать ради вкуса не стоит: экосистема Gin крупнее.
Echo быстрее Gin?
В свежих бенчмарках они идут рядом: оба на net/http, и узкое место обычно база данных, а не роутер. Выбирать между этими двумя по скорости — почти всегда потерянное время.
Термины урока
Ключевые понятия из этого урока — короткие определения в глоссарии. Наведите на термин, чтобы вспомнить, откройте карточку для подробностей и ссылки на практику.
Сравните с альтернативами
Практический вопрос после первых уроков: а почему именно эта библиотека? Мы разобрали конкурентов по одним критериям, с кодом одной задачи рядом и персональным подбором под ваши приоритеты.
Изучайте дальше
Следующая ступень учебного пути
GORM: ORM-библиотека для Go
Курс GORM: модели, CRUD, ассоциации, транзакции, хуки, пагинация, оптимизация запросов. 25 уроков с примерами и проектом слоя данных.
- Подключать БД и настраивать пул соединений
- Описывать модели и связи: 1:1, 1:N, M:N
- Писать CRUD и сложные выборки chainable-стилем
- Контролировать N+1 через Preload