Что такое API
API (Application Programming Interface) — это контракт, который позволяет одной программе общаться с другой. Веб-API говорит по HTTP: клиент отправляет запрос, сервер возвращает ответ — обычно с данными в формате JSON.
REST (Representational State Transfer) — самый распространённый стиль проектирования таких API. Это не протокол и не библиотека — это набор правил о том, как строить URL, методы и ответы. HTTP передаёт данные, а REST говорит, как их организовать.
Главная идея — ресурс: у каждой сущности, которой управляет ваш API — пользователь, заказ, фотография, — есть собственный URL, например /users/7.
Правила REST
REST опирается на несколько принципов:
Клиент — сервер — обе стороны разделены и развиваются независимо.
Без состояния — каждый запрос несёт всё, что нужно серверу; между запросами сервер ничего не запоминает.
Единообразный интерфейс — одни и те же URL, методы и коды состояния везде означают одно и то же.
Кэшируемость — ответ может сообщить «этот результат можно использовать повторно», экономя обращения к серверу.
Многослойность — прокси, шлюзы и балансировщики нагрузки могут находиться между клиентом и сервером, и ни одна из сторон этого не заметит.
Один запрос, один ответ
Любое взаимодействие с API — это такой цикл: уходит запрос (метод + URL + необязательное тело), приходит ответ (код состояния + заголовки + тело). Вот один полный цикл на Go — демонстрация запускает крошечный тестовый сервер, чтобы программа могла выполниться и завершиться сама.
Полный цикл запроса и ответа
Клиент запрашивает GET /users/1; сервер отвечает статусом 200 OK, типом содержимого и телом в формате JSON. Все страницы этой группы строятся на этом цикле.
Вывод: программа на Go и захваченный вывод
package main
import (
"fmt"
"io"
"net/http"
"net/http/httptest"
)
func main() {
// Крошечный сервер для демонстрации (настоящий использовал бы ListenAndServe).
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"id": 1, "name": "Ana"}`)
}))
defer server.Close()
resp, err := http.Get(server.URL + "/users/1")
if err != nil {
fmt.Println("запрос не удался:", err)
return
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println("запрос: GET /users/1")
fmt.Println("статус:", resp.Status)
fmt.Println("тип: ", resp.Header.Get("Content-Type"))
fmt.Println("тело: ", string(body))
}
Методы, коды состояния и ограничения
HTTP-методы соответствуют четырём операциям над данными (CRUD):
GET прочитать ресурс · POST создать · PUT заменить · PATCH изменить часть · DELETE удалить.
Коды состояния сообщают, как всё прошло: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error.
У REST есть и честные ограничения: он не создан для потоков в реальном времени, ответ может нести больше или меньше данных, чем хотел клиент, а версионирование публичного API требует дисциплины. Знать ограничения — часть знания стиля.