Go — это язык программирования с открытым исходным кодом, разработанный в Google и призванный помочь в создании простых надежных программных систем. Основным преимуществом Go являются его механизмы параллелизма, которые упрощают написание программного обеспечения и используют многоядерные архитектуры.
Это скомпилированный, строго — статически типизированный, параллельный и сборочный язык.
Это очень интересный современный язык из-за некоторых вариантов, которые были сделаны при его разработке. Например, система типов, хотя Go имеет методы, а также стиль программирования OO, иерархии типов не существует. Единственный способ добиться этого — через интерфейсы.
Как Go отличается от других
Нужно прочитать спецификацию языка, чтобы лучше понять элементы дизайна языка. Это действительно сжато и помогает выявить некоторые действительно интересные детали. Отличие Go от других типичных языков программирования состоит в том, что он отличается от других языков OO:
- Наследование без типов
- Нет перегрузки методов и операторов
- Построенный в примитивах параллелизма, которые действительно выделяют его из толпы. Он разделяет память, общаясь, а не наоборот.
- Набор инструментов, использующий традиционную модель компиляции и компоновки для генерации двоичных файлов без внешних зависимостей.
- Карты встроены.
Код организации
Код Go хранится в рабочих пространствах. Это просто иерархия каталогов, как показано ниже:
-
src
— содержит исходные файлы Go в виде пакетов -
pkg
— содержит объекты пакета -
bin
— содержит исполняемые файлы
Инструмент Go собирает исходные пакеты и устанавливает получившиеся двоичные файлы в каталогах bin
и pkg
.
Простое веб-приложение с использованием Go
Давайте создадим статический сайт, а затем продолжим его улучшать, чтобы он вел себя гораздо более динамично на основе пользовательского ввода.
Статический сайт
Структура кода для статического сайта выглядит так:
Таким образом, по сути вы хотели бы создать структуру, похожую на изображение выше или как показано в хранилище . Эта структура репо сама будет находиться в workspace
. Читайте о структуре кода Go для получения дополнительной информации.
Теперь мы хотим предоставить HTML-файл, находящийся в общедоступном каталоге.
Содержимое index.html
выглядит следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
<!DOCTYPE html>
<html>
<head>
<title>Static site using Go</title>
<link rel=»stylesheet» type=»text/css» href=»stylesheets/gostatic.css»>
</head>
<body>
<h1>Developing Website using Go</h1>
<p>I am a static page, being served to you with the help of Go lang.</p>
</body>
</html>
|
А вот программа Go для статической подачи файлов из общей папки:
01
02
03
04
05
06
07
08
09
10
|
package main
import (
«net/http»
)
func main() {
fs := http.FileServer(http.Dir(«public»))
http.ListenAndServe(«:8080», fs)
}
|
Позвольте мне объяснить:
- net / http — этот пакет обеспечивает реализацию клиента и сервера HTTP.
- FileServer — эта функция возвращает обработчик, который обслуживает HTTP-запросы с содержимым файловой системы.
Вот и все. Действительно просто и по существу. Вы можете запустить код, используя следующее: go run gostatic.go
.
Лучшее решение
Однако это решение не позволяет четко разделить проблемы маршрутизации и обслуживания, и, следовательно, лучшее решение будет следующим:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
package main
import (
«net/http»
«log»
)
func main() {
fs := http.FileServer(http.Dir(«public»))
http.Handle(«/», fs)
log.Println(«Listening…»)
err := http.ListenAndServe(«:8080», nil)
if err != nil {
log.Fatal(«ListenAndServe: «, err)
}
}
|
ListenAndServe
запускает HTTP-сервер по указанному TCP-адресу, а затем вызывает Serve с обработчиком. Этот обработчик обычно равен nil, так что маршрутизатор по умолчанию (в случае Go может взять на себя DefaultServerMux ).
Теперь что касается DefaultServeMux — давайте сделаем небольшой обход, чтобы понять, как Go выполняет обработку HTTP. Это делается с помощью двух основных вещей.
- ServerMuxes — (Маршрутизатор) Это мультиплексор — по сути, HTTP-маршрутизатор, который сравнивает входящие запросы с определенным списком и затем вызывает соответствующий обработчик.
- Обработчики. Они отвечают за «обработку» запроса, например за ответ с соответствующими заголовками, телом и т. Д. Любой объект, подчиняющийся интерфейсу обработчика, может действовать как один.
Запустите пример веб-приложения, как было сделано ранее, и вы должны увидеть результат!
Динамические сайты — добавление метки времени при каждом обновлении
Далее, напишем приложение так, чтобы оно печатало текущее время, подразумевая, что при каждом обновлении вы получаете разные выходные данные. Код Go будет выглядеть так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package main
import (
«fmt»
«net/http»
«time»
)
func main() {
http.HandleFunc(«/», handler)
log.Println(«listening…»)
err := http.ListenAndServe(«:8080», nil)
if err != nil {
panic(err)
}
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, «Hello. The time is : » + time.Now().Format(time.RFC850))
}
|
Здесь мы импортировали fmt
для работы с некоторыми функциями печати. Fmt реализует отформатированные функции ввода-вывода по аналогии с библиотекой stdio
.
Мы также использовали HandleFunc
который регистрирует путь URL с помощью функции-обработчика в DefaultServeMux . Обработчик функции имеет тип http.HandlerFunc
. Он принимает в качестве http.ResponseWriter
и http.Request
. Люди, знакомые с сервлетами Java, помнят это!
Чтобы распечатать время, мы импортируем «время» из стандартного пакета и используем его для ответа на объект модуля записи ответов. http.ResponseWriter
объект http.ResponseWriter
мы можем отправить ответ клиенту.
http.Request
— это структура, которая представляет HTTP-запрос и, следовательно, содержит все данные запроса. Для доступа к URL-пути мы делаем r.URL.path
.
Когда вы запустите это и получите доступ к localhost:8080
вы должны видеть текущее время при каждом обновлении.
Принятие пользовательского ввода
Теперь давайте напишем приложение, которое принимает username
на странице индекса, а затем, когда форма отправляется, оно приветствует пользователя на следующей странице.
Вот наша структура кода Go:
Давайте сначала создадим HTML-файл, содержащий форму внутри публичного каталога.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
<!DOCTYPE html>
<html>
<head>
<meta charset=»utf-8″>
<title>Go Greeter</title>
</head>
<body>
<h1>Go Greeter</h1>
<form action=»/greet» method=»post» accept-charset=»utf-8″>
<input type=»text» name=»username» id=»username» value=»Enter username…»>
<input type=»submit» value=»Greet me!»>
</form>
</body>
</html>
|
Эта форма после отправки будет перенаправлена на /greet
. Давайте также напишем содержимое файла greet.html
в общедоступном каталоге, которое мы будем отображать при greet.html
запроса в /greet
.
01
02
03
04
05
06
07
08
09
10
|
<!DOCTYPE html>
<html>
<head>
<meta charset=»utf-8″>
<title>Go Greeter</title>
</head>
<body>
<pre>Hello {{.}}</pre>
</body>
</html>
|
Код Go выглядит следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
package main
import (
«log»
«net/http»
«html/template»
)
func main() {
http.HandleFunc(«/», root)
http.HandleFunc(«/greet», greeter)
log.Println(«Listening…»)
err := http.ListenAndServe(«:8080», nil)
if err != nil {
log.Fatal(«ListenAndServe: «, err)
}
}
func root(w http.ResponseWriter, r *http.Request) {
t, _ := template.ParseFiles(«public/index.html»)
t.Execute(w, nil)
}
func greeter(w http.ResponseWriter, r *http.Request) {
username := r.FormValue(«username»)
t, _ := template.ParseFiles(«public/greeter.html»)
err := t.Execute(w, username)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
|
Мы использовали html/template
для хранения HTML-кода в шаблонах, а затем использовали их для визуализации по запросу.
В файле greeter.html
есть любопытный вид {{.}}
. В пакете html/template
предполагается, что простой текст создается всегда. Он добавляет экранирование там, где это необходимо для безопасного встраивания этой простой строки в правильный контекст. Когда значение данных не является простым текстом, мы можем убедиться, что оно не экранировано, указав его тип. По сути, Hey, {{.}}!
можно вызвать с помощью tmpl.Execute(out, HTML('<i>Nishant</i>'))
чтобы создать Hey, <i>Nishant</i>!
, Давай, попробуй это!
Поскольку основное приложение теперь работает, мы можем наконец развернуть его в Heroku.
Развертывание в Heroku
После того, как вы правильно настроите пояс для герою и управляете репозиторием через Git, мы можем развернуть его в этом направлении.
Единственное изменение, которое нам нужно сделать в коде для развертывания в Heroku, — это изменить строку, на которой мы слушаем определенный порт.
Изменить:
http.ListenAndServe(":8080",...)
чтобы:
http.ListenAndServe(":"+os.Getenv("PORT"),...
Настройка Heroku
Для развертывания в Heroku вам потребуется учетная запись пользователя Heroku. Вам также понадобится клиент командной строки Heroku. Получите его, установив Heroku Toolbelt, если это еще не сделано.
После установки войдите в систему, используя учетную запись Heroku, указав heroku login
, а затем загрузите свой SSH-ключ. С этими вещами вы должны быть готовы к развертыванию в Heroku.
Развертывание приложения
Для развертывания в Heroku нам нужно, чтобы приложение было сохранено в Git.
1
2
3
|
git init .
git add -A .
git commit -m ‘first heroku go app’
|
Нам также понадобится Procfile, чтобы сообщить Heroku, что команда, которую нужно запустить для веб-процесса, — это наше приложение.
1
|
echo ‘web: gogreeter’ > Procfile
|
Управление Godep
пакетов Go в Heroku осуществляется с помощью пакетов Godep
.
Установите Godep и сохраните ваши зависимости, используя следующее:
1
2
|
go get github.com/kr/godep
godep save
|
Добавьте эти новые файлы в Git:
1
2
|
git add -A .
git commit -m ‘godep’
|
Наконец, создайте приложение Heroku. Это можно сделать так:
1
|
heroku create -b https://github.com/kr/heroku-buildpack-go.git
|
Это должно создать Git Remote в вашем хранилище по имени heroku
. Вы готовы развернуть сейчас! Запустите следующее:
1
|
git push heroku master
|
После выполнения вышеуказанной команды ваше приложение должно быть запущено!
Перейдите на страницу URL, сказав, что heroku open
или heroku open
непосредственно к URL-адресу приложения, которое вы видите в консоли.
Вот и все. Теперь у вас есть приложение Go, запущенное на Heroku!
Резюме
Из этого руководства мы узнали, как легко разработать веб-приложение Go, а также развернуть его на Heroku. В наши дни веб-разработка во многом зависит от используемых сред. Чтобы изучить некоторые из этих вариантов, вы должны обязательно проверить некоторые из этих проектов.
- Хьюго
- мартини
- Revel
- Gorilla веб-инструментарий
- Hastie — Генератор статических сайтов в Go