Особую сферу разработки на Go занимает веб-программирование, которое представляет создание различных веб-приложений, в том числе различных веб-сайтов, веб-сервисов. Изначально Go не предназначался для веб-программирования и более того даже не рассматривался разработчиками в данной роли, и потребовалось некоторое время, прежде чем Go стал применяться в этой области. В то же время это не значит, что Go подойдет для всех веб-проектов. Многие веб-фреймворки содержат кучу готового функционала из коробки, который облегчает создание приложений. В Go подобного нет. Go предоставляет в основном только самые базовые вещи, на основании которых можно строить более сложные конструкции. Go в плане веб-разработки подойдет прежде всего для таких проектов, которые требуют очень высокой производительности, либо когда важны какие-то определенные возможности Go, например, параллельная обработка запросов.
Основной функционал для создания веб-приложений в Go расположен в пакете net/http. В частности, чтобы запустить веб-приложение, которое могло бы принимать входящие запросы, достаточно вызвать функцию http.ListenAndServe:
func ListenAndServe(addr string, handler Handler) error
Первый параметр указывает, запросы по какому пути будут обслуживаться веб-приложением. Второй параметр определяет обработчик запроса в виде интерфейса Handler.
Этот интерфейс определяет функцию ServeHTTP
:
type Handler interface { ServeHTTP(ResponseWriter, *Request) }
Функция ServeHTTP принимает два параметра. Первый параметр - объект ResponseWriter представляет поток ответа, в который мы моем записать любые данные, которые мы хотим отправить в ответ пользователю. Второй параметр - Request инкапсулирует всю информацию о запросе.
Например, определим простейшее веб-приложение. Для этого создадим на жестком диске каталог для хранения файлов с исходным кодом на языке Go, допустим, он будет называться golang. И определим в этом каталоге файл server.go со следующим кодом:
package main import ( "fmt" "net/http" ) type msg string func (m msg) ServeHTTP(resp http.ResponseWriter, req *http.Request) { fmt.Fprint(resp, m) } func main() { msgHandler := msg("Hello from Web Server in Go") fmt.Println("Server is listening...") http.ListenAndServe("localhost:8181", msgHandler) }
В данном случае определен кастомный тип msg на основе типа string, который реализует метод ServeHTTP интерфейса Handler. В самом методе с помощью
вызова fmt.Fprint(resp, m)
в поток ответа resp пишется сообщение, которое хранится в строке m. Таким образом, пользователю отправляется ответ.
В функции main определяется объект msgHandler:
msgHandler := msg("Hello from Web Server in Go")
По сути это строка, но тем не менее этот объект реализует интерфейс Handler.
Далее для обработки запросов передаем этот объект в качестве второго параметра в функцию http.ListenAndServe:
http.ListenAndServe("localhost:8181", msgHandler)
Первый параметр указывает, что веб-приложение будет запускаться по адресу localhost:8181
. Номер порта необязательно должен быть 8181.
Это может быть любой незанятый порт.
Запустим веб-приложение:
И затем в любом браузере обратимся по адресу "http://localhost:8181/":