http Лекция 6 Фёдор Короткий * Имеем из коробки - HTTP клиент (HTTP/1.x, HTTP/2) - HTTP сервер (с поддержкой TLS) - Тестирование * net/http * net/http Содержит в себе: - HTTP клиент и сервер - Константы статусов и методов HTTP - Sentinel ошибки - Вспомогательные функции для составления и разбора HTTP запросов * HTTP клиент * Делаем запрос .play simpleget/simpleget.go Доступные функции: Get(url string) (*Response, error) Post(url, contentType string, body io.Reader) (*Response, error) Head(url string) (*Response, error) PostForm(url string, form url.Values) (*Response, error) * Делаем более лучший запрос .play custompost/custompost.go /func/,/^}/ `http.DefaultClient` - базовый глобальный клиент с настройками по-умолчанию. * http.Client type Client struct { // Определяет механизм выполнения каждого запроса Transport RoundTripper // Функция для кастомной проверки редиректов // По-умолчанию - максимум 10 редиректов CheckRedirect func(req *Request, via []*Request) error // Хранилище кук Jar CookieJar // Таймаут любого запроса от клиента // Считается все время от соединения до конца вычитывания тела // 0 - без таймаута Timeout time.Duration } * Тонкая настройка клиента .code customclient/customclient.go /func main/,/^}/ * Keepalive .play keepalive/naive/naive.go /func main/,/^}/ Как-то медленно * Keepalive .play keepalive/advanced/advanced.go /func main/,/^}/ Что-то лыжи не едут * Keepalive .play keepalive/correct/correct.go /func main/,/^}/ Вот теперь всё как надо! * HTTP сервер * Простой HTTP сервер .code simpleserver/simpleserver.go /func RunServer/,/^}/ .code simpleserver/simpleserver.go /func RunTLSServer/,/^}/ * Простой HTTP сервер `http.Handler` - интерфейс, описывающий функцию для обработки HTTP запроса. type Handler interface { ServeHTTP(ResponseWriter, *Request) } type ResponseWriter interface { Header() Header WriteStatus(int) Write([]byte) (int, error) } * Роутинг .code simpleserver/router.go /func RunServerWithRouting/,/OMIT/ * Что нужно знать - Запуск сервера - блокирующая операция - Каждый входящий HTTP запрос обрабатывается в отдельной горутине (следите за дескрипторами) - Паника внутри одного хэндлера не приводит к остановке всего сервера - Неотловленная паника закрывает HTTP соединение - Хедеры ответа нельзя менять после вызова `ResponseWriter.WriteHeader` или `ResponseWriter.Write` * Middleware .code simpleserver/middleware.go /func RunServerWithMiddleware/,/^}/ * Middleware .code simpleserver/middleware.go /func UnifiedErrorMiddleware/,/^}/ * Graceful shutdown .play gracefulshutdown/gracefulshutdown.go /func run()/,/^}/ * Контекст в HTTP сервере .code context/httpserver/httpserver.go /type ReqTimeContextKey/,/^}/ * Контекст в HTTP сервере .code context/httpserver/handler.go /type handler/,/^}/ * httptest * httptest Содержит хелперы для удобного написания тестов для HTTP клиентов и серверов. // стартует новый локальный HTTP сервер на слуйчаном свободном порту httptest.NewServer(http.Handler) // объект, реализующий интерфейс http.ResponseWriter и дающий доступ к результатам ответа httptest.NewRecorder() // возвращает объект, готовый к передаче прямо в http.Handler httptest.NewRequest(method, target string, body io.Reader) *http.Request * Пример тестирования клиента .code httptest/code.go /^const \(/,/OMIT/ * Пример тестирования клиента .code httptest/code_test.go /func TestGetReposCount/,/OMIT/ * Пример тестирования сервера .code context/httpserver/handler_test.go /func TestHandlerServeHTTP/,/^}/ * Полезные библиотеки и фреймворки Клиент: .link https://github.com/go-resty/resty Роутеры: .link https://github.com/go-chi/chi .link https://github.com/julienschmidt/httprouter .link https://github.com/gorilla/mux Фреймворки: .link https://github.com/labstack/echo .link https://github.com/gin-gonic/gin .link https://github.com/gofiber/fiber