Go to file
Marek Goc 8813fe1aa9 add decimals 2023-04-23 22:16:37 +02:00
constants after fork 2023-04-11 22:43:48 +02:00
examples after fork 2023-04-11 22:43:48 +02:00
images after fork 2023-04-11 22:43:48 +02:00
router after fork 2023-04-11 22:43:48 +02:00
security after fork 2023-04-11 22:43:48 +02:00
swagger add decimals 2023-04-23 22:16:37 +02:00
templates after fork 2023-04-11 22:43:48 +02:00
.gitignore after fork 2023-04-11 22:43:48 +02:00
Dockerfile after fork 2023-04-11 22:43:48 +02:00
LICENSE after fork 2023-04-11 22:43:48 +02:00
Makefile after fork 2023-04-11 22:43:48 +02:00
README.md readme 2023-04-11 22:45:25 +02:00
fibers.go enable or disable swagger 2023-04-11 23:33:33 +02:00
go.mod add decimals 2023-04-23 22:16:37 +02:00
go.sum add decimals 2023-04-23 22:16:37 +02:00
group.go after fork 2023-04-11 22:43:48 +02:00

README.md

Fiber + Swagger = Fibers

Introduction

Fibers is a web framework based on Fiber and Swagger inspired by FastAPI, which wraps Fiber and provides built-in swagger api docs and request model validation.

Why I build this project?

Previous I have used FastAPI, which gives me a great experience in api docs generation and api writing, because nobody like writing api docs.

Now I use Fiber but I can't found anything like that, I found swag but which write docs with comment is so stupid. So there is Fibers.

Requirements

  • Go >= 1.18, because of generic usage.

Installation

go get -u github.com/long2ice/fibers

Online Demo

You can see online demo at https://fibers.long2ice.io/docs or https://fibers.long2ice.io/redoc.

docs redoc

And you can see the code in examples.

Usage

Build Swagger

Firstly, build a swagger object with basic information.

package examples

import (
  "github.com/getkin/kin-openapi/openapi3"
  "github.com/long2ice/fibers/swagger"
)

func NewSwagger() *swagger.Swagger {
  return swagger.New("Fibers", "Swagger + Fiber = Fibers", "0.1.0",
    swagger.License(&openapi3.License{
      Name: "Apache License 2.0",
      URL:  "https://github.com/long2ice/fibers/blob/dev/LICENSE",
    }),
    swagger.Contact(&openapi3.Contact{
      Name:  "long2ice",
      URL:   "https://github.com/long2ice",
      Email: "long2ice@gmail.com",
    }),
    swagger.TermsOfService("https://github.com/long2ice"),
  )
}

Write API

Then make func which is type F func(c *fiber.Ctx, req T) error.

package examples

import "github.com/gofiber/fiber/v2"

type TestQueryReq struct {
  Name string `query:"name" validate:"required" json:"name" description:"name of model" default:"test"`
}

func TestQuery(c *fiber.Ctx, req TestQueryReq) error {
  return c.JSON(req)
}

// TestQueryNoReq if there is no req body
func TestQueryNoReq(c *fiber.Ctx) error {
  return c.SendString("xxx")
}

All supported tags

name description
query binding query param
cookie binding cookie param
form binding form param
json binding json body
uri binding path param
header binding header param
validate validator support
description swagger docs param description
example swagger docs param example
default swagger docs param default value
embed embed struct params or body

Note that the attributes in TestQuery? Fibers will validate request and inject it automatically, then you can use it in handler easily.

Write Router

Then write router with some docs configuration and api.

package examples

var query = router.New(
  TestQuery,
  router.Summary("Test Query"),
  router.Description("Test Query Model"),
  router.Tags("Test"),
)

// if there is no req body
var query = router.NewX(
  TestQueryNoReq,
  router.Summary("Test Query"),
  router.Description("Test Query Model"),
  router.Tags("Test"),
)

Security

If you want to project your api with a security policy, you can use security, also they will be shown in swagger docs.

Current there is five kinds of security policies.

  • Basic
  • Bearer
  • ApiKey
  • OpenID
  • OAuth2
package main

var query = router.New(
  TestQuery,
  router.Summary("Test query"),
  router.Description("Test query model"),
  router.Security(&security.Basic{}),
)

Then you can get the authentication string by c.Locals(security.Credentials) depending on your auth type.

package main

import "github.com/gofiber/fiber/v2"

func TestQuery(c *fiber.Ctx, req TestQueryReq) error {
  user := c.Locals(security.Credentials).(security.User)
  fmt.Println(user)
  return c.JSON(req)
}

Mount Router

Then you can mount router in your application or group.

package main

import "github.com/gofiber/fiber/v2"

func main() {
  app := fibers.New(NewSwagger(), fiber.Config{})
  queryGroup := app.Group("/query", fibers.Tags("Query"))
  queryGroup.Get("", query)
  queryGroup.Get("/:id", queryPath)
  queryGroup.Delete("", query)
  app.Get("/noModel", noModel)
}

Start APP

Finally, start the application with routes defined.

package main

import (
  "github.com/gin-contrib/cors"
  "github.com/gofiber/fiber/v2"
  "github.com/long2ice/fibers"
)

func main() {
  app := fibers.New(NewSwagger(), fiber.Config{})
  app.Use(
    logger.New(),
    recover.New(),
    cors.New(),
  )
  subApp := fibers.New(NewSwagger(), fiber.Config{})
  subApp.Get("/noModel", noModel)
  app.Mount("/sub", subApp)
  app.Use(cors.New(cors.Config{
    AllowOrigins:     "*",
    AllowMethods:     "*",
    AllowHeaders:     "*",
    AllowCredentials: true,
  }))
  queryGroup := app.Group("/query", fibers.Tags("Query"))
  queryGroup.Get("/list", queryList)
  queryGroup.Get("/:id", queryPath)
  queryGroup.Delete("", query)

  app.Get("/noModel", noModel)

  formGroup := app.Group("/form", fibers.Tags("Form"), fibers.Security(&security.Bearer{}))
  formGroup.Post("/encoded", formEncode)
  formGroup.Put("", body)
  formGroup.Post("/file", file)

  log.Fatal(app.Listen(":8080"))
}

That's all! Now you can visit http://127.0.0.1:8080/docs or http://127.0.0.1:8080/redoc to see the api docs. Have fun!

Disable Docs

In some cases you may want to disable docs such as in production, just put nil to fibers.New.

app = fibers.New(nil, fiber.Config{})

SubAPP Mount

If you want to use sub application, you can mount another SwaGin instance to main application, and their swagger docs is also separate.

package main

import "github.com/gofiber/fiber/v2"

func main() {
  app := fibers.New(NewSwagger(), fiber.Config{})
  subApp := fibers.New(NewSwagger(), fiber.Config{})
  subApp.Get("/noModel", noModel)
  app.Mount("/sub", subApp)
}

ThanksTo

  • kin-openapi, OpenAPI 3.0 implementation for Go (parsing, converting, validation, and more).
  • Fiber, Express inspired web framework written in Go.

License

This project is licensed under the Apache-2.0 License.