瀏覽代碼

SVI Добавление текста

SVI 2 年之前
父節點
當前提交
d2a8fbe405
共有 2 個文件被更改,包括 570 次插入1 次删除
  1. 2 1
      README.md
  2. 568 0
      docs/lesson05.md

+ 2 - 1
README.md

@@ -5,4 +5,5 @@
 - [Занятие 1. Контексты](./docs/lesson01.md)
 - [Занятие 2. Каналы](./docs/lesson02.md)
 - [Занятие 3. Интерфейсы](./docs/lesson03.md)
-- [Занятие 4. GORM](./docs/lesson05.md)
+- [Занятие 4. GORM](./docs/lesson04.md)
+- [Занятие 5. Fiber](./docs/lesson05.md)

+ 568 - 0
docs/lesson05.md

@@ -0,0 +1,568 @@
+# Fiber
+
+**Fiber** -- высокопроизводительный веб-фреймворк для приложений на **Go**.
+
+[Домашняя страница Fiber](https://gofiber.io/)
+[Документация](https://docs.gofiber.io/)
+[примеры](https://github.com/gofiber/recipes)
+
+## Простейший пример
+
+```golang
+package main
+
+import "github.com/gofiber/fiber/v2"
+
+func main() {
+    app := fiber.New()
+
+    app.Get("/", func(c *fiber.Ctx) error {
+        return c.SendString("Hello, World!")
+    })
+
+    app.Listen(":3000")
+}
+```
+
+```bash
+go run server.go
+```
+
+По адресу `http://localhost:3000` можно посмотреть результат.
+
+## Примеры
+
+```golang
+// GET http://localhost:8080/hello%20world
+
+app.Get("/:value", func(c *fiber.Ctx) error {
+    return c.SendString("value: " + c.Params("value"))
+    // => Get request with value: hello world
+})
+
+
+// Опциональный параметр
+// GET http://localhost:3000/john
+app.Get("/:name?", func(c *fiber.Ctx) error {
+    if c.Params("name") != "" {
+        return c.SendString("Hello " + c.Params("name"))
+        // => Hello john
+    }
+    return c.SendString("Where is john?")
+})
+
+
+// Подстановочные символы
+// GET http://localhost:3000/api/user/john
+app.Get("/api/*", func(c *fiber.Ctx) error {
+    return c.SendString("API path: " + c.Params("*"))
+    // => API path: user/john
+})
+
+// Статические файлы
+app.Static("/", "./public")
+```
+
+## Конфигурирование
+
+```golang
+app := fiber.New(fiber.Config{
+    Prefork:       true,
+    CaseSensitive: true,
+    StrictRouting: true,
+    ServerHeader:  "Fiber",
+    AppName: "Test App v1.0.1",
+})
+
+
+// Работа с префорком
+app := fiber.New(fiber.Config{
+    Prefork: true,
+})
+
+if !fiber.IsChild() {
+    fmt.Println("I'm the parent process")
+} else {
+    fmt.Println("I'm a child process")
+}
+
+// Конфиг для статического обслуживания файлов
+app.Static("/", "./public", fiber.Static{
+  Compress:      true,
+  ByteRange:     true,
+  Browse:        true,
+  Index:         "john.html",
+  CacheDuration: 10 * time.Second,
+  MaxAge:        3600,
+})
+
+
+// Методы фреймворка
+func (app *App) Get(path string, handlers ...Handler) Router
+func (app *App) Head(path string, handlers ...Handler) Router
+func (app *App) Post(path string, handlers ...Handler) Router
+func (app *App) Put(path string, handlers ...Handler) Router
+func (app *App) Delete(path string, handlers ...Handler) Router
+func (app *App) Connect(path string, handlers ...Handler) Router
+func (app *App) Options(path string, handlers ...Handler) Router
+func (app *App) Trace(path string, handlers ...Handler) Router
+func (app *App) Patch(path string, handlers ...Handler) Router
+```
+
+## GET- POST-запросы
+
+```golang
+// Simple GET handler
+app.Get("/api/list", func(c *fiber.Ctx) error {
+  return c.SendString("I'm a GET request!")
+})
+
+// Simple POST handler
+app.Post("/api/register", func(c *fiber.Ctx) error {
+  return c.SendString("I'm a POST request!")
+})
+
+// Несколько маршрутов на доном обработчике
+// Match requests starting with /api or /home (multiple-prefix support)
+app.Use([]string{"/api", "/home"}, func(c *fiber.Ctx) error {
+    return c.Next()
+})
+```
+
+## Монтирование приложений
+
+```golang
+func main() {
+    app := fiber.New()
+    micro := fiber.New()
+    app.Mount("/john", micro) // GET /john/doe -> 200 OK
+
+    micro.Get("/doe", func(c *fiber.Ctx) error {
+        return c.SendStatus(fiber.StatusOK)
+    })
+
+    log.Fatal(app.Listen(":3000"))
+}
+```
+
+## Группы роутов
+
+```golang
+func main() {
+  app := fiber.New()
+
+  api := app.Group("/api", handler)  // /api
+
+  v1 := api.Group("/v1", handler)   // /api/v1
+  v1.Get("/list", handler)          // /api/v1/list
+  v1.Get("/user", handler)          // /api/v1/user
+
+  v2 := api.Group("/v2", handler)   // /api/v2
+  v2.Get("/list", handler)          // /api/v2/list
+  v2.Get("/user", handler)          // /api/v2/user
+
+  log.Fatal(app.Listen(":3000"))
+}
+```
+
+## Ограничение числа подключений
+
+```golang
+func main() {
+    app := fiber.New()
+
+    // Выключение без контекста и с контекстом
+    func (app *App) Shutdown() error
+    func (app *App) ShutdownWithTimeout(timeout time.Duration) error
+    func (app *App) ShutdownWithContext(ctx context.Context) error
+
+    app.Server().MaxConnsPerIP = 1
+
+    // ...
+}
+```
+
+## Работа с TLS
+
+```golang
+app.ListenTLS(":443", "./cert.pem", "./cert.key");
+```
+
+## работа с JSON
+
+```golang
+app.Get("/stack", func(c *fiber.Ctx) error {
+  return c.JSON(c.App().Stack())
+})
+```
+
+## РАбота с кукисами
+
+```golang
+app.Get("/user/delete", func(c *fiber.Ctx) error {
+    c.Cookie(&fiber.Cookie{
+        Name:     "token",
+        // Set expiry date to the past
+        Expires:  time.Now().Add(-(time.Hour * 2)),
+        HTTPOnly: true,
+        SameSite: "lax",
+    })
+
+    // ...
+})
+
+
+// Пример работы с кукисами
+app.Get("/", func(c *fiber.Ctx) error {
+  // Create cookie
+  cookie := new(fiber.Cookie)
+  cookie.Name = "john"
+  cookie.Value = "doe"
+  cookie.Expires = time.Now().Add(24 * time.Hour)
+
+  // Set cookie
+  c.Cookie(cookie)
+  // ...
+// Clears all cookies:
+  c.ClearCookie()
+
+  // Expire specific cookie by name:
+  c.ClearCookie("user")
+})
+```
+
+## Загрузка файлов
+
+```golang
+app.Get("/", func(c *fiber.Ctx) error {
+  return c.Download("./files/report-12345.pdf");
+  // => Download report-12345.pdf
+
+  return c.Download("./files/report-12345.pdf", "report.pdf");
+  // => Download report.pdf
+})
+```
+
+## Обработка вложений
+
+```golang
+app.Get("/", func(c *fiber.Ctx) error {
+  c.Attachment()
+  // => Content-Disposition: attachment
+
+  c.Attachment("./upload/images/logo.png")
+  // => Content-Disposition: attachment; filename="logo.png"
+  // => Content-Type: image/png
+
+  // ...
+})
+```
+
+## Редиректы
+
+```golang
+app.Get("/", func(c *fiber.Ctx) error {
+  return c.SendString("Home page")
+})
+app.Get("/test", func(c *fiber.Ctx) error {
+  c.Set("Content-Type", "text/html")
+  return c.SendString(`<a href="/back">Back</a>`)
+})
+
+app.Get("/back", func(c *fiber.Ctx) error {
+  return c.RedirectBack("/")
+})
+```
+
+## Пример ответа
+
+```golang
+app.Get("/", func(c *fiber.Ctx) error {
+  c.Response().BodyWriter().Write([]byte("Hello, World!"))
+  // => "Hello, World!"
+  return nil
+})
+
+app.Get("/", func(c *fiber.Ctx) error {
+  return c.Send([]byte("Hello, World!")) // => "Hello, World!"
+})
+
+. . .
+return c.SendString("Hello, World!")
+ // => "Hello, World!"
+
+. . .
+ return c.SendStream(bytes.NewReader([]byte("Hello, World!")))
+ // => "Hello, World!"
+
+```
+
+## Отправка статусов
+
+```golang
+app.Get("/not-found", func(c *fiber.Ctx) error {
+  return c.SendStatus(415)
+  // => 415 "Unsupported Media Type"
+
+  c.SendString("Hello, World!")
+  return c.SendStatus(415)
+  // => 415 "Hello, World!"
+})
+
+app.Get("/fiber", func(c *fiber.Ctx) error {
+  c.Status(fiber.StatusOK)
+  return nil
+}
+
+app.Get("/hello", func(c *fiber.Ctx) error {
+  return c.Status(fiber.StatusBadRequest).SendString("Bad Request")
+}
+
+app.Get("/world", func(c *fiber.Ctx) error {
+  return c.Status(fiber.StatusNotFound).SendFile("./public/gopher.png")
+})
+```
+
+## Установка заголовков
+
+```golang
+app.Get("/", func(c *fiber.Ctx) error {
+  c.Set("Content-Type", "text/plain")
+  // => "Content-type: text/plain"
+
+  // ...
+})
+```
+
+## Обработка XML
+
+```golang
+type SomeStruct struct {
+  XMLName xml.Name `xml:"Fiber"`
+  Name    string   `xml:"Name"`
+  Age     uint8    `xml:"Age"`
+}
+
+app.Get("/", func(c *fiber.Ctx) error {
+  // Create data struct:
+  data := SomeStruct{
+    Name: "Grame",
+    Age:  20,
+  }
+
+  return c.XML(data)
+  // <Fiber>
+  //     <Name>Grame</Name>
+  //    <Age>20</Age>
+  // </Fiber>
+})
+```
+
+## Запросы с помощью клиента Fiber (например, для прокси сервера)
+
+```golang
+// Get something
+func getSomething(c *fiber.Ctx) (err error) {
+    agent := fiber.Get("<URL>")
+    statusCode, body, errs := agent.Bytes()
+    if len(errs) > 0 {
+        return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
+            "errs": errs,
+        })
+    }
+
+    var something fiber.Map
+    err = json.Unmarshal(body, &something)
+    if err != nil {
+        return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
+            "err": err,
+        })
+    }
+
+    return c.Status(statusCode).JSON(something)
+}
+
+// Post something
+func createSomething(c *fiber.Ctx) (err error) {
+    agent := fiber.Post("<URL>")
+    agent.Body(c.Body()) // set body received by request
+    statusCode, body, errs := agent.Bytes()
+    if len(errs) > 0 {
+        return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
+            "errs": errs,
+        })
+    }
+    agent.ConnectionClose()
+    // pass status code and body received by the proxy
+    return c.Status(statusCode).Send(body)
+}
+
+// Авторизация с агентом
+func (a *Agent) BasicAuth(username, password string) *Agent
+func (a *Agent) BasicAuthBytes(username, password []byte) *Agent
+```
+
+## Логгер
+
+```golang
+import "github.com/gofiber/fiber/v2/log"
+
+log.SetLevel(log.LevelInfo)
+
+log.Info("info")
+log.Warn("warn")
+```
+
+## Мидэлвейр (несколько примеров)
+
+```golang
+package main
+
+import (
+    "fmt"
+    "net/http"
+
+    "github.com/gofiber/fiber/v2"
+    "github.com/gofiber/fiber/v2/middleware/adaptor"
+)
+
+func main() {
+    // New fiber app
+    app := fiber.New()
+
+    // http.Handler -> fiber.Handler
+    app.Get("/", adaptor.HTTPHandler(handler(greet)))
+
+    // http.HandlerFunc -> fiber.Handler
+    app.Get("/func", adaptor.HTTPHandlerFunc(greet))
+
+    // Listen on port 3000
+    app.Listen(":3000")
+}
+
+func handler(f http.HandlerFunc) http.Handler {
+    return http.HandlerFunc(f)
+}
+
+func greet(w http.ResponseWriter, r *http.Request) {
+    fmt.Fprint(w, "Hello World!")
+}
+```
+
+Пример ниже можно использовать совместно с `go-app` (* WebApp *)
+
+```golang
+package main
+
+import (
+    "net/http"
+
+    "github.com/gofiber/fiber/v2"
+    "github.com/gofiber/fiber/v2/middleware/adaptor"
+)
+
+func main() {
+    // fiber.Handler -> http.Handler
+    http.Handle("/", adaptor.FiberHandler(greet))
+
+    // fiber.Handler -> http.HandlerFunc
+    http.HandleFunc("/func", adaptor.FiberHandlerFunc(greet))
+
+    // Listen on port 3000
+    http.ListenAndServe(":3000", nil)
+}
+
+func greet(c *fiber.Ctx) error {
+    return c.SendString("Hello World!")
+}
+```
+
+## Сквозное сжатие (мидлвейр)
+
+```golang
+import (
+  "github.com/gofiber/fiber/v2"
+  "github.com/gofiber/fiber/v2/middleware/compress"
+)
+
+// Initialize default config
+app.Use(compress.New())
+
+// Or extend your config for customization
+app.Use(compress.New(compress.Config{
+    Level: compress.LevelBestSpeed, // 1
+}))
+
+// Skip middleware for specific routes
+app.Use(compress.New(compress.Config{
+  Next:  func(c *fiber.Ctx) bool {
+    return c.Path() == "/dont_compress"
+  },
+  Level: compress.LevelBestSpeed, // 1
+}))
+```
+
+## Разрешение CORS (мидлвейер)
+
+```golang
+// Initialize default config
+app.Use(cors.New())
+
+// Or extend your config for customization
+app.Use(cors.New(cors.Config{
+    AllowOrigins: "https://gofiber.io, https://gofiber.net",
+    AllowHeaders:  "Origin, Content-Type, Accept",
+}))
+```
+
+## обработка шаблонов
+
+```golang
+app.Get("/", func(c *fiber.Ctx) error {
+    return c.Render("index", fiber.Map{
+        "hello": "world",
+    });
+})
+```
+
+Поддерживаются шаблоны:
+
+- ace
+- amber
+- django (python)
+- handlebars
+- html
+- jet
+- mustache
+- pug
+- slim
+
+```golang
+package main
+
+import (
+    "log"
+    "github.com/gofiber/fiber/v2"
+    "github.com/gofiber/template/html/v2"
+)
+
+func main() {
+    // Initialize standard Go html template engine
+    engine := html.New("./views", ".html")
+    // If you want other engine, just replace with following
+    // Create a new engine with django
+    // engine := django.New("./views", ".django")
+
+    app := fiber.New(fiber.Config{
+        Views: engine,
+    })
+    app.Get("/", func(c *fiber.Ctx) error {
+        // Render index template
+        return c.Render("index", fiber.Map{
+            "Title": "Hello, World!",
+        })
+    })
+
+    log.Fatal(app.Listen(":3000"))
+}
+```