Самый простой способ создать REST API с помощью Go
Go известен тем, что его легко освоить и он обеспечивает самый быстрый путь к созданию продукта. Благодаря встроенной в стандартную библиотеку функциональности HTTP у вас есть все необходимое без каких-либо внешних зависимостей. Низкоуровневый доступ к HTTP
может стать глотком свежего воздуха, если вы привыкли к раздутым платформам, но это приводит к появлению большого количества шаблонного кода, который со временем становится утомительным для написания снова и снова. Здесь на помощь приходит babyapi
. Я создал эту библиотеку, чтобы обеспечить очень простое создание REST API, не навязывая определенную структуру всему приложению. Это так просто, что справится даже ребенок!
BabyAPI
Все, что вам нужно для начала работы с babyapi
, — это структура, реализующая интерфейс babyapi.Resource
. Этого легко достичь путем расширения структуры babyapi.DefaultResource
. После выполнения этого простого шага у вас будет HTTP API, способный выполнять операции создания, чтения, обновления и удаления. Кроме того, babyapi
предоставляет HTTP-клиент для взаимодействия с API, интерфейс командной строки для удобного использования этого клиента и несколько ярлыков для модульного тестирования.
babyapi
также может вывести вас за рамки основ. Он предоставляет множество возможностей для расширения поведения API, добавления проверки и даже пользовательских маршрутов API. Любую серверную часть хранилища можно интегрировать, реализовав простой интерфейс хранилища.
Эта статья лишь поверхностно описывает возможности babyapi
. Если вы хотите узнать больше, следите за моими будущими статьями и отмечайте репозиторий GitHub.
Начало работы
Цель babyapi
— сделать это настолько простым, чтобы это мог сделать даже ребенок. Как упоминалось ранее, babyapi.DefaultResource
уже реализует необходимый интерфейс, поэтому его можно использовать в качестве отправной точки для простых типов ресурсов. Помимо простой реализации интерфейса, эта структура по умолчанию реализует некоторые проверки идентификатора и использует rs/xid для создания уникального идентификатора для новых ресурсов.
Вот простой пример, который расширяет значение по умолчанию для создания API для элементов TODO
:
package main
import "github.com/calvinmclean/babyapi"
type TODO struct {
babyapi.DefaultResource
Title string
Description string
Completed bool
}
func main() {
api := babyapi.NewAPI[*TODO](
"TODOs", "/todos",
func() *TODO { return &TODO{} },
)
api.RunCLI()
}
Далее все, что вам нужно сделать, это запустить сервер и использовать CLI
для взаимодействия с ним:
go run main.go serve
В этой статье слишком много функций, поэтому лучшие способы узнать больше:
- Мои будущие статьи :)
Клиент
Структура, используемая для создания сервера, также позволяет встроенному клиенту взаимодействовать с сервером babyapi
. Клиент также можно использовать в приложении или других приложениях Go, взаимодействующих с вашим API. Он поддерживает ресурсы API верхнего уровня и вложенные ресурсы API и обеспечивает легкий доступ ко всем конечным точкам CRUD
.
// Create a client from an existing API struct (mostly useful for unit testing):
client := api.Client(serverURL)
// Create a client from the Resource type:
client := babyapi.NewClient[*TODO](addr, "/todos")
// Create a new TODO item
todo, err := client.Post(context.Background(), &TODO{Title: "use babyapi!"})
// Get an existing TODO item by ID
todo, err := client.Get(context.Background(), todo.GetID())
// Get all incomplete TODO items
incompleteTODOs, err := client.GetAll(context.Background(), url.Values{
"completed": []string{"false"},
})
// Delete a TODO item
err := client.Delete(context.Background(), todo.GetID())
Клиент предоставляет более общие методы взаимодействия с сервером: MakeRequest
и MakeRequestWithResponse
. Клиент также настраиваемый. Вы можете заменить базовый http.Client
, чтобы использовать собственный RoundTripper
, или использовать SetRequestEditor
, чтобы добавить функцию предварительного запроса, которая изменяет http.Request
.
Хранилище
Вы можете перенести любую серверную часть хранилища в babyapi
, реализовав интерфейс Storage
. По умолчанию API будет использовать встроенный MapStorage
, который просто использует карту в памяти.
Чтобы обеспечить реальное постоянное хранилище «из коробки», пакет babyapi/storage
использует madflojo/hord для поддержки различных серверных частей хранилища «ключ-значение». Кроме того, babyapi/storage
предоставляет вспомогательные функции для инициализации клиента Hord для Redis или файлового хранилища.
db, err := storage.NewFileDB(hashmap.Config{
Filename: "storage.json",
})
db, err := storage.NewRedisDB(redis.Config{
Server: "localhost:6379",
})
api.SetStorage(storage.NewClient[*TODO](db, "TODO"))
Заключение и дорожная карта
babyapi
— очень новый проект, и у него еще большой потенциал для новых функций и улучшений. Однако моя цель — сделать его максимально простым и простым, поэтому я планирую сосредоточиться на улучшении удобства использования и тестирования. Я добавлю новые функции, если появятся варианты использования или запросы на функции. Вот некоторые из следующих вещей:
- Улучшите CLI, чтобы получить более удобные инструкции по использованию и реализовать флаги, когда для вложенных API требуется несколько идентификаторов.
- Улучшите ведение журнала по умолчанию и внедрите уровни журнала.
- Разрешить CLI доступ к конечным точкам, не относящимся к CRUD (конечным точкам, добавленным с помощью
AddCustomRoute
илиAddCustomIDRoute
).
- Создайте больше автоматизированного тестирования. В идеале я создам генератор, который читает ваш исходный файл с помощью
babyapi
и генерирует структуру тестов с некоторыми тестами по умолчанию и возможностью их расширения.
Также следите за другими статьями, в которых более подробно рассматриваются некоторые основные функции babyapi
!