Реализация веб-сервиса с помощью Go и Fiber

Реализация веб-сервиса с помощью Go и Fiber

20 октября 2022 г.

Принципы веб-разработки одинаковы для всех веб-фреймворков. Давайте изучим основы веб-разработки с помощью языка программирования Go и фреймворка Fiber и напишем самый простой веб-сервис.

Какие причины существования фреймворков?

Каждый популярный веб-сервис основан на обмене данными между клиентами и серверами. Постоянно повторяющаяся обработка запросов и возврат ответов включает в себя множество элементов, аналогичных большинству сайтов.

Мы не хотим разрабатывать аналогичные инструменты для каждого нового сайта. Мы хотим создавать повторно используемые инструменты для похожей логики, а не изобретать каждый раз что-то новое. Фреймворки были разработаны для этих целей. Они включали механизмы для стандартных вопросов веб-разработки. Благодаря фреймворкам мы не можем быстрее решать бизнес-задачи и практически пропускать низкоуровневые технические вопросы.

Запросы и ответы

Большинство современных веб-фреймворков основаны на парадигме ответ-запрос и не зависят от языка программирования и особенностей реализации.

Давайте реализуем самый простой веб-сервер с фреймворком Fiber, чтобы понять его внешний вид. Файбер минималистичный, но быстрый и содержит все необходимые инструменты для реализации. Инструкции по установке можно найти на сайте.

Привет, мир!

Давайте напишем простейшее приложение с помощью Fiber. Традиционно это будет веб-сервер, который возвращает Hello, World! Создайте файл server.go со следующим содержимым:

package main 

import "github.com/gofiber/fiber/v2"

func main() {
    app := fiber.New()

    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("Hello, World!")
    })

    app.Listen(":3000")
}

Запустите приложение с помощью команды в терминале

go run server.go

В браузере введите http://localhost:3000 и увидите текст Hello, World!

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

  1. В этом фрагменте кода мы создаем пакет с именем main. В каждом пакете Go есть функция main, и наш код не исключение.
  2. Импортируйте необходимый модуль инфраструктуры Fiber.
  3. В начале функции main мы создаем новый экземпляр нашего веб-сервера. Он будет обслуживать запросы и выполнять работу.
  4. Следующий шаг — обработка маршрута /. Интернет-запросы имеют адрес или URL. Нам не нужен порт или домен, если мы уже внутри сервера, чтобы отправить наш запрос на обработку. Нам нужен только путь от исходного адреса и метод, используемый в запросе.
  5. Мы рассмотрим другие параметры более подробно позже, а пока предположим, что сервер будет обрабатывать запрос GET с кратчайшим путем / и отправлять строку в ответ, используя Контекстный метод SendString.
  6. В функцию-обработчик передается параметр с указателем на структуру контекста. Хотя дизайн и советы специфичны для нашей платформы, понятие контекста, связанного с запросом, является универсальным. Контекст запроса содержит необходимую информацию и методы для обработки текущего запроса.
  7. Компоненты объектов ответа и запроса — заголовки с метаинформацией
  8. В последней строке нашей функции main мы указываем, какой порт сервера будет обрабатываться. Здесь 3000, но подойдет любой порт. Вы можете запускать несколько экземпляров одного и того же сервера на разных портах.

Обработку запроса мы написали на /, а как дальше идти и обрабатывать остальные запросы. В конце концов, мы хотим, чтобы наш сервер мог делать что-то еще.

Более сложный обработчик

Каждый запрос, поступающий на сервер, имеет адрес. Для нашего сервера, пока он работает локально на нашей машине, адрес выглядит так: http://localhost:3000/resource. Браузер уже знает, что наш сервер работает по адресу localhost:3000, поэтому мы не обрабатываем эту часть внутри, а обрабатываем часть ресурсов. Если мы отправляем запрос из адресной строки браузера — используется метод GET, поэтому внутри нашего фреймворка мы повторяем обработчик адреса /, который у нас уже есть. Это будет выглядеть так:

app.Get("/resource", func(c *fiber.Ctx) error {
    return c.SendString("Desired resource")
})

Перезапускаем сервер, и, введя ссылку в браузере, получаем результат - строку Желаемый ресурс.

Как видно из примера, первый параметр функции с именем метода HTTP-запроса отвечает за обработку определенного пути в Файбере. Функция-обработчик, указанная вторым параметром, отвечает за результат, возвращаемый по конкретному запросу. Сопоставление пути и обработчика на веб-сервере называется маршрутизацией и является обязательным шагом в каждой веб-инфраструктуре.

Динамический адрес

Адреса могут быть динамическими и содержать такие параметры, как идентификатор пользователя или название фильма. Внутри Fiber также есть готовый функционал для этого. Давайте реализуем обработчик запросов со следующим параметром http://localhost:3000/resource/resource_id

.

app.Get("/resource/:id", func(c *fiber.Ctx) error {
    return c.SendString("Desired resource = " + c.Params("id"))
})

Двоеточие перед именем параметра позволит нам получить это значение в обработчике запроса, что мы и демонстрируем, добавляя идентификатор ресурса в ответ. Может быть более одного параметра, что позволяет реализовать сложную маршрутизацию.

Вот что такое маршрут и обработчик запросов с двумя параметрами http://localhost:3000/user/8427/book/HarryPotterandtheChamberofSecrets< /a> будет выглядеть так:

Параметры запроса

Помимо включения параметров непосредственно в путь запроса, переменные заменяются в параметрах запроса. Вы, наверное, видели такие URL-адреса, как http://localhost:3000/book_cover?size=140x200&filename=cover .png Параметры в URL-адресах в основном используются для указания идентификатора объекта или имени, а параметры запроса используются для передачи любой информации. Это хорошо зарекомендовавшая себя практика, но ничто не помешает вам передать что-либо в качестве параметра URL.

Конечно, существуют ограничения по длине — многие веб-сервисы не допускают очень длинных URL-адресов. Если вам нужно много данных, вы должны использовать запрос POST и передавать параметры не в URL, а в теле запроса. Ниже давайте посмотрим код для обработки параметра запроса. Функция контекста Query используется для получения параметра из запроса.

app.Get("/book_cover", func(c *fiber.Ctx) error {
    return c.SendString("Desired book cover has size " + c.Query("size") + " with filename " + c.Query("filename"))
})

Пересохраняем код, и после вызова нашего URL получаем параметры из запроса в ответ. Очень важно получить параметры в обработчике и убедиться, что они имеют правильный формат и значения. Этот шаг называется проверкой.

Структура запроса

В обработчике откройте структуру запроса и просмотрите необходимую информацию. Fiber скрывает работу с методом запроса и настраивает маршрутизацию без усилий с нашей стороны. Вы можете получить метод напрямую следующим образом:

app.Get("/", func(c *fiber.Ctx) error {
  c.Request().Header.Method()
  // => []byte("GET")
})

Как видим, контекстный метод Request вернет всю необходимую информацию.

Структура ответа

Если в контексте есть объект запроса, очевидно, что есть и объект ответа. К нему также часто требуется доступ. Сценарии использования разнообразны: вернуть тип возвращаемого ответа, сохранить ключ для хеширования и добавить информацию об авторизации. Эти данные записываются в заголовки ответа. Однако вы не должны возвращать файлы в заголовках, и также есть ограничение по размеру.

Fiber содержит полезные методы, которые скрывают необработанный ответ, но объект ответа доступен, если вы хотите, как показано в следующем фрагменте кода:

// GET http://localhost:3000/custom_header
app.Get("/custom_header", func(c *fiber.Ctx) error {
    c.Response().Header.Set("X-My-Header", "my-header-value")
    return c.SendString("Hello, World!")
})

Если вы запросите URL-адрес в браузере, вы получите стандартный ответ Hello, World!. Вы можете увидеть заголовки в консоли разработчика или с помощью таких инструментов, как cUrl или Postman.

Заключение

Сегодня мы рассмотрели несколько концепций разработки веб-приложений. Тем не менее, стоит еще раз вспомнить — независимо от языка программирования и фреймворка вам придется работать с HTTP-запросами.

Вы сами выбираете, добавлять ли параметры непосредственно в URL-адрес или добавлять их в качестве параметров запроса. Сделать запросы GET или POST и что добавить или удалить из заголовков. Если вы хотите использовать язык программирования Go и фреймворк Fiber, вам помогут готовые примеры из сегодняшнего урока.

Полезные ссылки

Официальный сайт Go

официальный сайт Fiber

Что такое URL?

Весь список

Весь код приложения из текущей статьи прикреплен ниже:

package main

import "github.com/gofiber/fiber/v2"

func main() {
    app := fiber.New()

    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("Hello, World!")
    })

    app.Get("/resource", func(c *fiber.Ctx) error {
        return c.SendString("Desired resource")
    })

    app.Get("/resource/:id", func(c *fiber.Ctx) error {
        return c.SendString("Desired resource = " + c.Params("id"))
    })

    app.Get("/user/:id/book/:title", func(c *fiber.Ctx) error {
        return c.SendString("Desired book is " + c.Params("title") + " from user " + c.Params("id"))
    })

    app.Get("/bookfile", func(c *fiber.Ctx) error {
        return c.SendString("Desired bookfile has size " + c.Query("size") + " with filename " + c.Query("filename"))
    })

    app.Get("/custom_header", func(c *fiber.Ctx) error {
        c.Response().Header.Set("X-My-Header", "my-header-value")
        return c.SendString("Hello, World!")
    })

    app.Listen(":3000")
}


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE