Skip to content

Commit

Permalink
Support swagger (#24)
Browse files Browse the repository at this point in the history
* Support swagger

* Add swagger fmt

* Fix fmt

* Setup swagger host according to server port
  • Loading branch information
slhmy authored Sep 19, 2023
1 parent e2681ca commit 4098f8c
Show file tree
Hide file tree
Showing 9 changed files with 236 additions and 12 deletions.
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
OS := $(shell uname -s)

.PHONY: install-tools
install-tools:
go install github.com/swaggo/swag/cmd/swag@latest

.PHONY: build
build:
build: install-tools
@echo "Building on $(OS)"
swag fmt -d application/server
swag init -d application/server -ot go -o application/server/swaggo-gen
go mod tidy
go build -o bin/migrate_db application/migrate_db/main.go
go build -o bin/service application/server/main.go
Expand Down
4 changes: 2 additions & 2 deletions application/server/handler/problem.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"github.com/gin-gonic/gin"
)

func SetupProblemRoute(r *gin.Engine) {
g := r.Group("/api/v1/problem")
func SetupProblemRoute(baseRoute *gin.RouterGroup) {
g := baseRoute.Group("/problem")
{
g.GET("/greet", func(c *gin.Context) {
c.String(http.StatusOK, "Hello, this is problem service")
Expand Down
33 changes: 33 additions & 0 deletions application/server/handler/swaggo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package handler

import (
swaggoGen "github.com/OJ-lab/oj-lab-services/application/server/swaggo-gen"
"github.com/gin-gonic/gin"
"github.com/spf13/viper"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
)

const (
servicePortProp = "service.port"
)

var (
swaggerHost string
)

func SetupSwaggoRouter(r *gin.RouterGroup) {
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}

func init() {
sevicePort := viper.GetString(servicePortProp)
swaggerHost = "localhost" + sevicePort
println("Swagger host is set to: " + swaggerHost)
// programmatically set swagger info
swaggoGen.SwaggerInfo.Title = "OJ Lab Services API"
swaggoGen.SwaggerInfo.Version = "1.0"
swaggoGen.SwaggerInfo.Host = swaggerHost
swaggoGen.SwaggerInfo.BasePath = "/api/v1"
swaggoGen.SwaggerInfo.Schemes = []string{"http"}
}
27 changes: 22 additions & 5 deletions application/server/handler/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"github.com/gin-gonic/gin"
)

func SetupUserRouter(r *gin.Engine) {
g := r.Group("/api/v1/user")
func SetupUserRouter(baseRoute *gin.RouterGroup) {
g := baseRoute.Group("/user")
{
g.GET("/health", func(ginCtx *gin.Context) {
ginCtx.String(http.StatusOK, "Hello, this is user service")
Expand All @@ -22,10 +22,19 @@ func SetupUserRouter(r *gin.Engine) {
}

type loginBody struct {
Account string `json:"account"`
Password string `json:"password"`
Account string `json:"account" example:"admin"`
Password string `json:"password" example:"admin"`
}

// Login
//
// @Summary Login by account and password
// @Description A Cookie will be set if login successfully
// @Tags user
// @Accept json
// @Param loginBody body loginBody true "body"
// @Router /user/login [post]
// @Success 200
func login(ginCtx *gin.Context) {
body := &loginBody{}
err := ginCtx.BindJSON(body)
Expand All @@ -41,9 +50,17 @@ func login(ginCtx *gin.Context) {
}
middleware.SetLoginSessionCookie(ginCtx, *lsId)

ginCtx.String(http.StatusOK, "")
ginCtx.Status(http.StatusOK)
}

// Me
//
// @Summary Get current user
// @Description If correctly logined with cookie, return current user
// @Tags user
// @Router /user/me [get]
// @Success 200
// @Failure 401
func me(ginCtx *gin.Context) {
ls := middleware.GetLoginSession(ginCtx)
if ls == nil {
Expand Down
21 changes: 17 additions & 4 deletions application/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,45 @@ package main

import (
"github.com/OJ-lab/oj-lab-services/application/server/handler"
"github.com/sirupsen/logrus"

"github.com/OJ-lab/oj-lab-services/core"
"github.com/OJ-lab/oj-lab-services/core/middleware"
"github.com/gin-gonic/gin"
)

const (
servicePortProp = "service.port"
serviceModeProp = "service.mode"
servicePortProp = "service.port"
serviceModeProp = "service.mode"
serveSwaggerProp = "service.swagger_on"
)

var (
servicePort string
serviceMode string
swaggerOn bool
)

func init() {
servicePort = core.AppConfig.GetString(servicePortProp)
serviceMode = core.AppConfig.GetString(serviceModeProp)
swaggerOn = core.AppConfig.GetBool(serveSwaggerProp)
}

func main() {
r := gin.Default()
r.Use(middleware.HandleError)
gin.SetMode(serviceMode)
handler.SetupUserRouter(r)
handler.SetupProblemRoute(r)

baseRouter := r.Group("/")
if swaggerOn {
logrus.Info("Serving swagger Doc...")
handler.SetupSwaggoRouter(baseRouter)
}

apiRouter := r.Group("/api/v1")
handler.SetupUserRouter(apiRouter)
handler.SetupProblemRoute(apiRouter)

err := r.Run(servicePort)
if err != nil {
Expand Down
97 changes: 97 additions & 0 deletions application/server/swaggo-gen/docs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Package swaggo_gen Code generated by swaggo/swag. DO NOT EDIT
package swaggo_gen

import "github.com/swaggo/swag"

const docTemplate = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"contact": {},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/user/login": {
"post": {
"description": "A Cookie will be set if login successfully",
"consumes": [
"application/json"
],
"tags": [
"user"
],
"summary": "Login by account and password",
"parameters": [
{
"description": "body",
"name": "loginBody",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handler.loginBody"
}
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/user/me": {
"get": {
"description": "If correctly logined with cookie, return current user",
"tags": [
"user"
],
"summary": "Get current user",
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized"
}
}
}
}
},
"definitions": {
"handler.loginBody": {
"type": "object",
"properties": {
"account": {
"type": "string",
"example": "admin"
},
"password": {
"type": "string",
"example": "admin"
}
}
}
}
}`

// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "",
Host: "",
BasePath: "",
Schemes: []string{},
Title: "",
Description: "",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate,
LeftDelim: "{{",
RightDelim: "}}",
}

func init() {
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
}
1 change: 1 addition & 0 deletions config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ auth_on = true
port = ":8080"
cookie.age = "24h"
mode = "debug"
swagger_on = true

[judger]
host = "http://localhost:8000"
Expand Down
14 changes: 14 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ require (
github.com/google/uuid v1.3.1
github.com/sirupsen/logrus v1.9.3
github.com/spf13/viper v1.16.0
github.com/swaggo/swag v1.16.2
gorm.io/driver/postgres v1.5.2
gorm.io/gorm v1.25.4
)

require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/bytedance/sonic v1.10.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
Expand All @@ -19,11 +23,17 @@ require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect
github.com/go-openapi/spec v0.20.4 // indirect
github.com/go-openapi/swag v0.19.15 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jackc/pgx/v5 v5.4.3 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
Expand All @@ -36,7 +46,9 @@ require (
github.com/subosito/gotenv v1.6.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
golang.org/x/arch v0.4.0 // indirect
golang.org/x/tools v0.7.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

Expand All @@ -61,6 +73,8 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
github.com/redis/go-redis/v9 v9.1.0
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.0
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/net v0.14.0 // indirect
Expand Down
Loading

0 comments on commit 4098f8c

Please sign in to comment.