У вас включен AdBlock или иной блокировщик рекламы.

Пожалуйста, отключите его, доход от рекламы помогает развитию сайта и появлению новых статей.

Спасибо за понимание.

В другой раз
DevGang блог о програмировании
Авторизоваться

Встраивание статических ресурсов в проект Go 

Я хотел создать небольшое автономное веб-приложение на Go, противоположное обычному веб-приложению, где ресурсы будут обслуживаться отдельно через CDN или HTTP-сервер, такой как Nginx. Но если производительность не имеет значения или она нацелена на небольшой трафик, то наличие автономного приложения облегчает его развертывание и распространение, поскольку это просто исполняемый двоичный файл.

Существует несколько пакетов, которые позволяют встраивать ресурсы в приложение Go:

Я не буду вдаваться в подробности каждой библиотеки, но я предпочел подход bindata, более простой для начала и активно поддерживаемый. Кроме того, шаг для встраивания ресурсов очень явно прописывается в коде.

Во-первых, вам нужно будет настроить рабочее пространство Go. Если вы не знакомы с Go, то вы можете обратиться к документации или моему предыдущему сообщению по этой теме.

После того, как вы получили рабочее пространство Go и настройку проекта, давайте создадим index.html внутри каталога frontend/ в вашем проекте. Со следующим контентом (Обратите внимание что пробел после < нужно убрать):


< html>
 < body>
   Hello, World!
 < /body>
< /html>

Теперь, когда у нас есть настройка проекта и статический ресурс для тестирования, давайте установим bindata с помощью команды:

go get -u github.com/jteeuwen/go-bindata/...

Мы готовы запустить бэкэнд-код веб-приложения. Создайте файл main.go и скопируйте следующий код:

package mainimport (
   "bytes"
   "io"
 "net/http"
)

//go:generate go-bindata -prefix "frontend/" -pkg main -o bindata.go frontend/...

func static_handler(rw http.ResponseWriter, req *http.Request) {
 var path string = req.URL.Path
 if path == "" {
   path = "index.html"
 }
 if bs, err := Asset(path); err != nil {
   rw.WriteHeader(http.StatusNotFound)
 } else {
   var reader = bytes.NewBuffer(bs)
   io.Copy(rw, reader)
 }
}

func main() {
 http.Handle("/", http.StripPrefix("/", http.HandlerFunc(static_handler)))
   http.ListenAndServe(":3000", nil)
}

Важная строка в этом коде:

//go:generate go-bindata -prefix "frontend/" -pkg main -o bindata.go frontend/...

Строка выше позволяет нам запускать командную строку go-bindata при вызове go generate. Начиная с версии 1.4, на этапе генерации можно запускать пользовательские команды . Это просто вопрос добавления //go:generate command argument... в ваш файл go.

Командная строка go-bindata имеет несколько параметров, поэтому ознакомьтесь с документацией по ее использованию. В нашем случае мы говорим:

  • -prefix "frontend/" определить часть имени пути для статики
  • -pkg main определить имя пакета, используемое в сгенерированном коде
  • -o bindata.go определить имя сгенерированного файла

После выполнения команды go generate вы должны увидеть генерируемый файл с именем bindata.go. Структура вашего проекта должна выглядеть так:

.
│ 
├── bindata.go (auto-generated file)
├── frontend
│   └── index.html
└── main.go

Логика для обслуживания статических файлов находится в функции static_handler, которая получает запрос и проверяет, соответствует ли путь к статике. Проверка выполняется с помощью функции Asset, автоматически экспортируемой пользователем bindata.go. Если ресурс не существует, мы возвращаем 404, в противном случае мы возвращаем содержимое ресурса.

Остальная часть кода предназначена для создания веб-приложения и связывания нашего шаблона static_handler с соответствием всеми входящим запросам на /. Если у вас возникли проблемы с пониманием этого кода, посмотрите документацию к пакету http.

В качестве быстрого напоминания о том, как Go обрабатывает пакеты, все идентификаторы будут автоматически экспортированы в другие пакеты с тем же именем, если первая буква имени идентификатора начинается с заглавной буквы.

Основываясь на этом правиле, файл bindata.go предоставляет функцию Asset для пакета main. Это загружает и возвращает русурс для данного имени. Он возвращает ошибку, если ресурс не может быть найден или не может быть загружен.

#Golang
Присоеденяйся в тусовку

Будь всегдя вкурсе новостей из мира IT