Code Monkey home page Code Monkey logo

fibers's Introduction

Fiber + Swagger = Fibers

deploy Go Reference

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: "[email protected]",
    }),
    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.

fibers's People

Contributors

long2ice avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

fibers's Issues

Inject custom validator

Would it be possible to inject my own validator ?
I have defined a few custom validators but with the current version, I am stuck doing a second validation.

var validate = validator.New()

Thanks !

有没有可能支持一下非请求结构体的方法作为handle的场景?

在v2看到帖子想尝试一下,然后发现按照readme的例子的话,所有的路由都必须用一个结构体接收请求信息,然后用结构体的一个方法作为实际的路由。

但我的handler已经定义成了结构体的一个方法(Handler{log,cache,metrics...}.GetUser(*fiber.Ctx) error),我的log等等基础组件都绑在这个结构体上,也不可能移到别的地方去。这样一来就没办法跟这个库一起使用。

有没有可能支持一下?

Support const enums

When I used Swaggo, I was able to do something like this:

type PaginationModel struct {
	Search   string  
	Take     int  
	Page     int    
	SortOrder SortOrder
}

type SortOrder string

const (
	SortOrderAsc  SortOrder = "asc"
	SortOrderDesc SortOrder = "desc"
)

this is the result:
image
I was able to select an enum from the dropdown list in Swagger UI.

But when I try this in fibers

type PaginationModel struct {
	Search    string    `query:"search"`
	Take      int       `query:"take"`
	Page      int       `query:"page"`
	SortOrder SortOrder `query:"sortOrder"`
}

type SortOrder string

const (
	SortOrderAsc  SortOrder = "asc"
	SortOrderDesc SortOrder = "desc"
)

it gives me a stack overflow

runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc020680360 stack=[0xc020680000, 0xc040680000]
fatal error: stack overflow

I tried using validate:"oneof=asc desc", it didn't render a dropdown list, and it would be painful to enter every value if I have a lot of const enums, for example: database table fields.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.