Страница 1 из 2
GO: WEB
Добавлено: 29 фев 2024, 16:22
Olej
Сколько раз по жизни зарекался никогда не ввязываться в WEB разработку ... не поддаваться никаким соблазнам и обещаниям ...
Но ситуация время от времени к тому склоняет...
GO: WEB
Добавлено: 29 фев 2024, 17:20
Olej
Olej писал(а): ↑29 фев 2024, 16:22
время от времени к тому склоняет...
Простейший WEB-сервер в пакетах Go включили с самого его начала, ещё от создания...
Тривиальный WEB-сервер я показывал ещё в книге:
Книга: "Linux: многопроцессорная эффективность. Выбираем Go" (в бумаге изданная она называлась по-другому, но тема осталась так).
Код: Выделить всё
package main
import (
"fmt"
"net/http"
)
type Hello struct{}
func (h Hello) ServeHTTP(
w http.ResponseWriter,
r *http.Request) {
fmt.Fprint(w, "Hello!")
}
func main() {
var h Hello
http.ListenAndServe("localhost:4000", h)
}
Вот всего то
- http.png (17.95 КБ) 142 просмотра
Но если заниматься WEB (кто любит), то всё дело в контенте...
GO: WEB
Добавлено: 29 фев 2024, 17:32
Olej
Olej писал(а): ↑29 фев 2024, 17:20
всё дело в контенте...
Как обрабатывать и что возвращать?
И тут на помощь приходит микрофреймворк Fiber - очень популярный (почему то
) у WEB разработчиков Go.
Хорошая статья вводная (и просто без усложенения, и достаточно для понимания)
Что такое микрофреймворк Fiber
Там есть готовый пример, который можно сразу опробовать (проверка на применимость
- с этого всегда начинаем!)
Код: Выделить всё
package main
import (
"fmt"
"net/http"
"github.com/gofiber/fiber/v2"
"github.com/sirupsen/logrus"
)
const profileUnknown = "unknown"
func main() {
webApp := fiber.New()
webApp.Get("/profiles", func(c *fiber.Ctx) error {
profileID := c.Query("profile_id", profileUnknown)
if profileID == "" {
profileID = profileUnknown
}
if profileID == profileUnknown {
return c.Status(http.StatusUnprocessableEntity).SendString("profile_id is required")
}
return c.SendString(fmt.Sprintf("User Profile ID: %s", profileID))
})
logrus.Fatal(webApp.Listen(":80"))
}
GO: WEB
Добавлено: 29 фев 2024, 17:36
Olej
Olej писал(а): ↑29 фев 2024, 17:32
проверка на применимость
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ go build fiber.go
fiber.go:7:5: no required module provides package github.com/gofiber/fiber/v2: go.mod file not found in current directory or any parent directory; see 'go help modules'
fiber.go:8:5: no required module provides package github.com/sirupsen/logrus: go.mod file not found in current directory or any parent directory; see 'go help modules'
Это понятно: внешний импорт ... нужно создать манифест модуля и прописать импорт...
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ go mod init fiber
go: creating new go.mod: module fiber
go: to add module requirements and sums:
go mod tidy
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ go mod tidy
go: finding module for package github.com/sirupsen/logrus
go: finding module for package github.com/gofiber/fiber/v2
go: downloading github.com/sirupsen/logrus v1.9.3
go: downloading github.com/gofiber/fiber v1.14.6
go: downloading github.com/gofiber/fiber/v2 v2.52.1
go: found github.com/gofiber/fiber/v2 in github.com/gofiber/fiber/v2 v2.52.1
go: found github.com/sirupsen/logrus in github.com/sirupsen/logrus v1.9.3
go: downloading golang.org/x/sys v0.15.0
go: downloading github.com/valyala/bytebufferpool v1.0.0
go: downloading github.com/google/uuid v1.5.0
go: downloading github.com/mattn/go-colorable v0.1.13
go: downloading github.com/mattn/go-isatty v0.0.20
go: downloading github.com/mattn/go-runewidth v0.0.15
go: downloading github.com/valyala/fasthttp v1.51.0
go: downloading gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
go: downloading github.com/klauspost/compress v1.17.0
go: downloading github.com/andybalholm/brotli v1.0.5
go: downloading github.com/valyala/tcplisten v1.0.0
Сборка:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ go build fiber.go
Теперь всё путём:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ ls -l fiber*
-rwxrwxr-x 1 olej olej 8421299 фев 29 15:00 fiber
-rw-rw-r-- 1 olej olej 660 фев 29 14:40 fiber.go
-rw-rw-r-- 1 olej olej 1980 фев 29 14:56 fiber.hist
GO: WEB
Добавлено: 29 фев 2024, 18:06
Olej
Olej писал(а): ↑29 фев 2024, 17:36
Сборка:
Пробуем выполнение:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ ./fiber
FATA[0000] failed to listen: listen tcp4 :80: bind: permission denied
Понятно ... привилегированный порт, 80 ...
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ sudo ./fiber
[sudo] пароль для olej:
FATA[0000] failed to listen: listen tcp4 :80: bind: address already in use
Вот так ... значит кто-то уже сидит у меня на этом стандартном порту...
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ sudo netstat -tunlp | grep ":80"
tcp6 0 0 :::80 :::* LISTEN 1482/apache2
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ ps -A | grep apache
1482 ? 00:00:00 apache2
1516 ? 00:00:00 apache2
1517 ? 00:00:00 apache2
1518 ? 00:00:00 apache2
1519 ? 00:00:00 apache2
1520 ? 00:00:00 apache2
30270 ? 00:00:00 apache2
Ясно ... это Apache сидит у меня на стандартном порту ... как итог многочисленных ежедневных разных экспериментов...
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ systemctl --no-pager --full status apache2
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2024-02-29 10:07:18 EET; 5h 18min ago
Docs: https://httpd.apache.org/docs/2.4/
Process: 1391 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
Main PID: 1482 (apache2)
Tasks: 7 (limit: 115772)
Memory: 27.5M
CPU: 1.102s
CGroup: /system.slice/apache2.service
├─ 1482 /usr/sbin/apache2 -k start
├─ 1516 /usr/sbin/apache2 -k start
├─ 1517 /usr/sbin/apache2 -k start
├─ 1518 /usr/sbin/apache2 -k start
├─ 1519 /usr/sbin/apache2 -k start
├─ 1520 /usr/sbin/apache2 -k start
└─30270 /usr/sbin/apache2 -k start
фев 29 10:07:18 R420 systemd[1]: Starting The Apache HTTP Server...
фев 29 10:07:18 R420 apachectl[1436]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
фев 29 10:07:18 R420 systemd[1]: Started The Apache HTTP Server.
Нужно останавливать ... или ("и" точнее) искать как пересаживать Fiber на другой порт.
GO: WEB
Добавлено: 29 фев 2024, 18:13
Olej
Olej писал(а): ↑29 фев 2024, 18:06
Нужно останавливать ...
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ sudo systemctl stop apache2
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ systemctl --no-pager --full status apache2
○ apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Thu 2024-02-29 15:28:19 EET; 30s ago
Docs: https://httpd.apache.org/docs/2.4/
Process: 1391 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
Process: 34319 ExecStop=/usr/sbin/apachectl graceful-stop (code=exited, status=0/SUCCESS)
Main PID: 1482 (code=exited, status=0/SUCCESS)
CPU: 1.208s
фев 29 10:07:18 R420 systemd[1]: Starting The Apache HTTP Server...
фев 29 10:07:18 R420 apachectl[1436]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
фев 29 10:07:18 R420 systemd[1]: Started The Apache HTTP Server.
фев 29 15:28:19 R420 systemd[1]: Stopping The Apache HTTP Server...
фев 29 15:28:19 R420 apachectl[34322]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
фев 29 15:28:19 R420 systemd[1]: apache2.service: Deactivated successfully.
фев 29 15:28:19 R420 systemd[1]: Stopped The Apache HTTP Server.
фев 29 15:28:19 R420 systemd[1]: apache2.service: Consumed 1.208s CPU time.
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ systemctl is-enabled apache2
enabled
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ sudo systemctl disable apache2
Synchronizing state of apache2.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable apache2
Removed /etc/systemd/system/multi-user.target.wants/apache2.service.
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/web/fiber$ systemctl is-enabled apache2
disabled
И запуск Fiber...
- Снимок экрана от 2024-02-29 17-11-20.png (61.75 КБ) 141 просмотр
GO: WEB
Добавлено: 29 фев 2024, 18:22
Olej
Olej писал(а): ↑29 фев 2024, 18:13
И запуск Fiber...
И со стороны браузера:
Ну что ж... Это всё славненько собралось и работает.
Теперь можно:
1). на базе этого сделать себе какое-то более осмысленное приложение...
2). иметь в виду ещё и возможность совместимости с
Go: WebAssembly (WASM)
GO: WEB
Добавлено: 29 фев 2024, 19:52
Olej
Olej писал(а): ↑29 фев 2024, 16:22
зарекался никогда не ввязываться в WEB разработку
То, что было ссылкой на PDF несколько лет назад - стало целой книжкой ... где-то в дебрях Google:
Build Web Application With Golang
(Можете отсюда скачивать PDF)
- Снимок экрана от 2024-02-29 18-48-34.png (243.77 КБ) 140 просмотров
327 страниц
GO: WEB
Добавлено: 29 фев 2024, 19:59
Olej
Olej писал(а): ↑29 фев 2024, 18:06
искать как пересаживать Fiber на другой порт
Код: Выделить всё
package main
import (
"fmt"
"net/http"
"github.com/gofiber/fiber/v2"
"github.com/sirupsen/logrus"
)
const profileUnknown = "unknown"
func main() {
webApp := fiber.New()
webApp.Get("/profiles", func(c *fiber.Ctx) error {
profileID := c.Query("profile_id", profileUnknown)
if profileID == "" {
profileID = profileUnknown
}
if profileID == profileUnknown {
return c.Status(http.StatusUnprocessableEntity).SendString("profile_id is required")
}
return c.SendString(fmt.Sprintf("User Profile ID: %s", profileID))
})
logrus.Fatal(webApp.Listen(":5000"))
}
Всего то
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/net/fiber$ go build fiber.go
Запуск:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/net/fiber$ ./fiber
┌───────────────────────────────────────────────────┐
│ Fiber v2.52.1 │
│ http://127.0.0.1:5000 │
│ (bound on host 0.0.0.0 and port 5000) │
│ │
│ Handlers ............. 2 Processes ........... 1 │
│ Prefork ....... Disabled PID ............. 56825 │
└───────────────────────────────────────────────────┘
... порт 5000 - запуск без sudo ...
Браузер (адрес + результат):
GO: WEB
Добавлено: 01 мар 2024, 03:02
Olej
Olej писал(а): ↑29 фев 2024, 19:59
"github.com/gofiber/fiber/v2"
Описание пакета здесь:
https://pkg.go.dev/github.com/gofiber/fiber/v2
Там огромный API ... не зря WEB-инарщики
так полюбили этот микрофреймворк
А если там де ещё и почитать документацию
:
Query возвращает параметр строки запроса в URL-адресе. По умолчанию используется пустая строка «», если запрос не существует. Если указано значение по умолчанию, оно вернет это значение, если запрос не существует. Возвращаемое значение действительно только внутри обработчика. Не сохраняйте никаких ссылок. Сделайте копии или используйте параметр Immutable, чтобы использовать значение вне обработчика.
... то и пример можно существенно упростить и сделать более понятным:
Код: Выделить всё
package main
import (
"fmt"
"net/http"
"github.com/gofiber/fiber/v2"
"github.com/sirupsen/logrus"
)
func main() {
handler := func(c *fiber.Ctx) error {
profileID := c.Query("profile_id")
if profileID == "" {
return c.Status(http.StatusUnprocessableEntity).
SendString("profile_id is required\n")
}
return c.SendString(fmt.
Sprintf("User Profile ID: %s\n", profileID))
}
webApp := fiber.New()
webApp.Get("/profiles", handler )
logrus.Fatal(webApp.Listen(":5000"))
}