syntax = "v1"

info (
	title:                  "演示 API" // 對應 swagger 的 title
	description:            "演示 api 生成 swagger 文件的 api 完整寫法" // 對應 swagger 的 description
	version:                "v1" // 對應 swagger 的 version
	termsOfService:         "https://github.com/zeromicro/go-zero" // 對應 swagger 的 termsOfService
	contactName:            "keson.an" // 對應 swagger 的 contactName
	contactURL:             "https://github.com/zeromicro/go-zero" // 對應 swagger 的 contactURL
	contactEmail:           "example@gmail.com" // 對應 swagger 的 contactEmail
	licenseName:            "MIT" // 對應 swagger 的 licenseName
	licenseURL:             "https://github.com/zeromicro/go-zero" // 對應 swagger 的 licenseURL
	consumes:               "application/json" // 對應 swagger 的 consumes，不填預設為 application/json
	produces:               "application/json" // 對應 swagger 的 produces，不填預設為 application/json
	schemes:                "http,https" // 對應 swagger 的 schemes，不填預設為 https
	host:                   "example.com" // 對應 swagger 的 host，不填預設為 127.0.0.1
	basePath:               "/v1" // 對應 swagger 的 basePath，不填預設為 /
	wrapCodeMsg:            true // 是否用 code-msg 通用回應體，如果開啟，則以格式 {"code":0,"msg":"OK","data":$data} 包括回應體
	bizCodeEnumDescription: "1001-未登入<br>1002-無權限操作" // 全域業務錯誤碼列舉描述，json 格式，key 為業務錯誤碼，value 為該錯誤碼的描述，僅當 wrapCodeMsg 為 true 時生效
	// securityDefinitionsFromJson 為自訂鑑權配置，json 內容將直接放入 swagger 的 securityDefinitions 中，
	// 格式參考 https://swagger.io/specification/v2/#security-definitions-object
	// 在 api 的 @server 中可宣告 authType 來指定其路由使用的鑑權類型
	securityDefinitionsFromJson: `{"apiKey":{"description":"apiKey 類型鑑權自訂","type":"apiKey","name":"x-api-key","in":"header"}}`
    useDefinitions: true// 開啟宣告將生成 models 進行關聯，definitions 僅對回應體和 json 請求體生效
)

type (
	QueryReq {
		Id     int    `form:"id,range=[1:10000],example=10"`
		Name   string `form:"name,example=keson.an"`
		Avatar string `form:"avatar,optional,example=https://example.com/avatar.png"`
	}
	QueryResp {
		Id   int    `json:"id,example=10"`
		Name string `json:"name,example=keson.an"`
	}
	PathQueryReq {
		Id   int    `path:"id,range=[1:10000],example=10"`
		Name string `form:"name,example=keson.an"`
	}
	PathQueryResp {
		Id   int    `json:"id,example=10"`
		Name string `json:"name,example=keson.an"`
	}
)

@server (
	tags:    "query 演示" // 對應 swagger 的 tags，可以對 swagger 中的 api 進行分組
	summary: "query 類型介面集合" // 對應 swagger 的 summary
	prefix: v1
	authType: apiKey // 指定該路由使用的鑑權類型，值為 securityDefinitionsFromJson 中定義的名稱
	group:"demo"
)
service Swagger {
	@doc (
		description: "query 接口"
		bizCodeEnumDescription: " 1003-用不存在<br>1004-非法操作" // 介面級別業務錯誤碼列舉描述，會覆蓋全域的業務錯誤碼，json 格式，key 為業務錯誤碼，value 為該錯誤碼的描述，僅當 wrapCodeMsg 為 true 且 useDefinitions 為 false 時生效
	)
	@handler query
	get /query (QueryReq) returns (QueryResp)

	@doc (
		description: "query path 中包含 id 欄位介面"
	)
	@handler queryPath
	get /query/:id (PathQueryReq) returns (PathQueryResp)
}

type (
	FormReq {
		Id   int    `form:"id,range=[1:10000],example=10"`
		Name string `form:"name,example=keson.an"`
	}
	FormResp {
		Id   int    `json:"id,example=10"`
		Name string `json:"name,example=keson.an"`
	}
)

@server (
	tags:    "form 表單 api 演示" // 對應 swagger 的 tags，可以對 swagger 中的 api 進行分組
	summary: "form 表單類型介面集合" // 對應 swagger 的 summary
)
service Swagger {
	@doc (
		description: "form 接口"
	)
	@handler form
	post /form (FormReq) returns (FormResp)
}

type (
	JsonReq {
		Id       int    `json:"id,range=[1:10000],example=10"`
		Name     string `json:"name,example=keson.an"`
		Avatar   string `json:"avatar,optional"`
		Language string `json:"language,options=golang|java|python|typescript|rust"`
		Gender   string `json:"gender,default=male,options=male|female,example=male"`
	}
	JsonResp {
		Id       int    `json:"id"`
		Name     string `json:"name"`
		Avatar   string `json:"avatar"`
		Language string `json:"language"`
		Gender   string `json:"gender"`
	}
	ComplexJsonLevel2 {
		// basic
		Integer int     `json:"integer,example=1"`
		Number  float64 `json:"number,example=1.1"`
		Boolean bool    `json:"boolean,options=true|false,example=true"`
		String  string  `json:"string,example=some text"`
	}
	ComplexJsonLevel1 {
		// basic
		Integer int     `json:"integer,example=1"`
		Number  float64 `json:"number,example=1.1"`
		Boolean bool    `json:"boolean,options=true|false,example=true"`
		String  string  `json:"string,example=some text"`
		// Object
		Object        ComplexJsonLevel2  `json:"object"`
		PointerObject *ComplexJsonLevel2 `json:"pointerObject"`
	}
	ComplexJsonReq {
		// basic
		Integer int     `json:"integer,example=1"`
		Number  float64 `json:"number,example=1.1"`
		Boolean bool    `json:"boolean,options=true|false,example=true"`
		String  string  `json:"string,example=some text"`
		// basic array
		ArrayInteger []int     `json:"arrayInteger"`
		ArrayNumber  []float64 `json:"arrayNumber"`
		ArrayBoolean []bool    `json:"arrayBoolean"`
		ArrayString  []string  `json:"arrayString"`
		// basic array array
		ArrayArrayInteger [][]int     `json:"arrayArrayInteger"`
		ArrayArrayNumber  [][]float64 `json:"arrayArrayNumber"`
		ArrayArrayBoolean [][]bool    `json:"arrayArrayBoolean"`
		ArrayArrayString  [][]string  `json:"arrayArrayString"`
		// basic map
		MapInteger map[string]int     `json:"mapInteger"`
		MapNumber  map[string]float64 `json:"mapNumber"`
		MapBoolean map[string]bool    `json:"mapBoolean"`
		MapString  map[string]string  `json:"mapString"`
		// basic map array
		MapArrayInteger map[string][]int     `json:"mapArrayInteger"`
		MapArrayNumber  map[string][]float64 `json:"mapArrayNumber"`
		MapArrayBoolean map[string][]bool    `json:"mapArrayBoolean"`
		MapArrayString  map[string][]string  `json:"mapArrayString"`
		// basic map map
		MapMapInteger map[string]map[string]int     `json:"mapMapInteger"`
		MapMapNumber  map[string]map[string]float64 `json:"mapMapNumber"`
		MapMapBoolean map[string]map[string]bool    `json:"mapMapBoolean"`
		MapMapString  map[string]map[string]string  `json:"mapMapString"`
		MapMapObject  map[string]map[string]ComplexJsonLevel1  `json:"mapMapObject"`
		MapMapPointerObject  map[string]map[string]*ComplexJsonLevel1  `json:"mapMapPointerObject"`
		// Object
		Object        ComplexJsonLevel1  `json:"object"`
		PointerObject *ComplexJsonLevel1 `json:"pointerObject"`
		// Object array
		ArrayObject        []ComplexJsonLevel1  `json:"arrayObject"`
		ArrayPointerObject []*ComplexJsonLevel1 `json:"arrayPointerObject"`
		// Object map
		MapObject        map[string]ComplexJsonLevel1  `json:"mapObject"`
		MapPointerObject map[string]*ComplexJsonLevel1 `json:"mapPointerObject"`
		// Object array array
		ArrayArrayObject        [][]ComplexJsonLevel1  `json:"arrayArrayObject"`
		ArrayArrayPointerObject [][]*ComplexJsonLevel1 `json:"arrayArrayPointerObject"`
		// Object array map
		ArrayMapObject        []map[string]ComplexJsonLevel1  `json:"arrayMapObject"`
		ArrayMapPointerObject []map[string]*ComplexJsonLevel1 `json:"arrayMapPointerObject"`
		// Object map array
		MapArrayObject        map[string][]ComplexJsonLevel1  `json:"mapArrayObject"`
		MapArrayPointerObject map[string][]*ComplexJsonLevel1 `json:"mapArrayPointerObject"`
	}
	ComplexJsonResp {
		// basic
		Integer int     `json:"integer,example=1"`
		Number  float64 `json:"number,example=1.1"`
		Boolean bool    `json:"boolean,options=true|false,example=true"`
		String  string  `json:"string,example=some text"`
		// basic array
		ArrayInteger []int     `json:"arrayInteger"`
		ArrayNumber  []float64 `json:"arrayNumber"`
		ArrayBoolean []bool    `json:"arrayBoolean"`
		ArrayString  []string  `json:"arrayString"`
		// basic array array
		ArrayArrayInteger [][]int     `json:"arrayArrayInteger"`
		ArrayArrayNumber  [][]float64 `json:"arrayArrayNumber"`
		ArrayArrayBoolean [][]bool    `json:"arrayArrayBoolean"`
		ArrayArrayString  [][]string  `json:"arrayArrayString"`
		// basic map
		MapInteger map[string]int     `json:"mapInteger"`
		MapNumber  map[string]float64 `json:"mapNumber"`
		MapBoolean map[string]bool    `json:"mapBoolean"`
		MapString  map[string]string  `json:"mapString"`
		// basic map array
		MapArrayInteger map[string][]int     `json:"mapArrayInteger"`
		MapArrayNumber  map[string][]float64 `json:"mapArrayNumber"`
		MapArrayBoolean map[string][]bool    `json:"mapArrayBoolean"`
		MapArrayString  map[string][]string  `json:"mapArrayString"`
		// basic map map
		MapMapInteger map[string]map[string]int     `json:"mapMapInteger"`
		MapMapNumber  map[string]map[string]float64 `json:"mapMapNumber"`
		MapMapBoolean map[string]map[string]bool    `json:"mapMapBoolean"`
		MapMapString  map[string]map[string]string  `json:"mapMapString"`
		MapMapObject  map[string]map[string]ComplexJsonLevel1  `json:"mapMapObject"`
		MapMapPointerObject  map[string]map[string]*ComplexJsonLevel1  `json:"mapMapPointerObject"`
		// Object
		Object        ComplexJsonLevel1  `json:"object"`
		PointerObject *ComplexJsonLevel1 `json:"pointerObject"`
		// Object array
		ArrayObject        []ComplexJsonLevel1  `json:"arrayObject"`
		ArrayPointerObject []*ComplexJsonLevel1 `json:"arrayPointerObject"`
		// Object map
		MapObject        map[string]ComplexJsonLevel1  `json:"mapObject"`
		MapPointerObject map[string]*ComplexJsonLevel1 `json:"mapPointerObject"`
		// Object array array
		ArrayArrayObject        [][]ComplexJsonLevel1  `json:"arrayArrayObject"`
		ArrayArrayPointerObject [][]*ComplexJsonLevel1 `json:"arrayArrayPointerObject"`
		// Object array map
		ArrayMapObject        []map[string]ComplexJsonLevel1  `json:"arrayMapObject"`
		ArrayMapPointerObject []map[string]*ComplexJsonLevel1 `json:"arrayMapPointerObject"`
		// Object map array
		MapArrayObject        map[string][]ComplexJsonLevel1  `json:"mapArrayObject"`
		MapArrayPointerObject map[string][]*ComplexJsonLevel1 `json:"mapArrayPointerObject"`
	}
)

@server (
	tags:    "post json api 演示" // 對應 swagger 的 tags，可以對 swagger 中的 api 進行分組
	summary: "json 請求類型介面集合" // 對應 swagger 的 summary
)
service Swagger {
	@doc (
		description: "簡單的 json 請求體介面"
	)
	@handler jsonSimple
	post /json/simple (JsonReq) returns (JsonResp)

	@doc (
		description: "複雜的 json 請求體介面"
	)
	@handler jsonComplex
	post /json/complex (ComplexJsonReq) returns (ComplexJsonResp)
}

