GO: WEB

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

GO: WEB

Непрочитанное сообщение Olej » 29 фев 2024, 16:22

Сколько раз по жизни зарекался никогда не ввязываться в WEB разработку ... не поддаваться никаким соблазнам и обещаниям ... :oops:
Но ситуация время от времени к тому склоняет... :cry:

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

GO: WEB

Непрочитанное сообщение Olej » 29 фев 2024, 17:20

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)
}
Вот всего то :lol:
http.png
http.png (17.95 КБ) 134 просмотра
Но если заниматься WEB (кто любит), то всё дело в контенте...

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

GO: WEB

Непрочитанное сообщение Olej » 29 фев 2024, 17:32

Olej писал(а):
29 фев 2024, 17:20
всё дело в контенте...
Как обрабатывать и что возвращать?
И тут на помощь приходит микрофреймворк Fiber - очень популярный (почему то :?: ) у WEB разработчиков Go.
Хорошая статья вводная (и просто без усложенения, и достаточно для понимания) Что такое микрофреймворк Fiber
Там есть готовый пример, который можно сразу опробовать (проверка на применимость :lol: - с этого всегда начинаем!)

Код: Выделить всё

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"))
}
Вложения
fiber.go
(659 байт) 4 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

GO: WEB

Непрочитанное сообщение Olej » 29 фев 2024, 17:36

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

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

GO: WEB

Непрочитанное сообщение Olej » 29 фев 2024, 18:06

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 на другой порт.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

GO: WEB

Непрочитанное сообщение Olej » 29 фев 2024, 18:13

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
Снимок экрана от 2024-02-29 17-11-20.png (61.75 КБ) 133 просмотра

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

GO: WEB

Непрочитанное сообщение Olej » 29 фев 2024, 18:22

Olej писал(а):
29 фев 2024, 18:13
И запуск Fiber...
И со стороны браузера:
http://localhost/profiles
profile_id is required
Ну что ж... Это всё славненько собралось и работает.
Теперь можно:
1). на базе этого сделать себе какое-то более осмысленное приложение...
2). иметь в виду ещё и возможность совместимости с Go: WebAssembly (WASM)

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

GO: WEB

Непрочитанное сообщение Olej » 29 фев 2024, 19:52

Olej писал(а):
29 фев 2024, 16:22
зарекался никогда не ввязываться в WEB разработку
То, что было ссылкой на PDF несколько лет назад - стало целой книжкой ... где-то в дебрях Google:
Build Web Application With Golang
(Можете отсюда скачивать PDF)
Снимок экрана от 2024-02-29 18-48-34.png
Снимок экрана от 2024-02-29 18-48-34.png (243.77 КБ) 132 просмотра
327 страниц

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

GO: WEB

Непрочитанное сообщение Olej » 29 фев 2024, 19:59

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 ...
Браузер (адрес + результат):

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

GO: WEB

Непрочитанное сообщение Olej » 01 мар 2024, 03:02

Olej писал(а):
29 фев 2024, 19:59
"github.com/gofiber/fiber/v2"
Описание пакета здесь: https://pkg.go.dev/github.com/gofiber/fiber/v2
Там огромный API ... не зря WEB-инарщики :lol: так полюбили этот микрофреймворк :!:
А если там де ещё и почитать документацию :lol: :
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"))
}
Вложения
fiber.go
(606 байт) 4 скачивания

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 10 гостей