GoFrame創建RestApi
現在有個api要對外開放
url設計
goods
: 商品列表頁面, 可以在url上制定排序方式,條件查詢,分頁查詢goods/{id}
:對應id
的單個商品
api寫法
package goods
import (
"Demo/app/model/df_goods_sku"
"Demo/app/service"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
"strings"
)
// 定義排序規則
// 如果獲取到的排序的字符串是以-開頭的,那么則將它定義為倒序,如果沒有就為正序
func GetOrderSort(s string) (string, string) {
if strings.HasPrefix(s, "-") {
return s[1:], "desc"
} else {
return s, "asc"
}
}
// 從url中獲取分頁的請求參數
// 默認的頁數是第一頁,默認是10行數據
func GetPageData(r *ghttp.Request) (int, int) {
page := r.GetQueryInt("page", 1)
page_size := r.GetQueryInt("page_size", 10)
return page, page_size
}
type Goods struct{}
// 設置查詢的字段
func (*Goods) GetFilterSetFields() []string {
return []string{
df_goods_sku.Columns.Name,
df_goods_sku.Columns.Price,
}
}
func (*Goods) GetOrderingSetFields() []string {
return []string{
df_goods_sku.Columns.CreateTime,
df_goods_sku.Columns.Id,
}
}
func (this *Goods) GetDefaultOrdering() string {
return df_goods_sku.Columns.Id + " " + "asc"
}
// 從URL參數中獲取查詢字符串的鍵值對
func (this *Goods) GetFilterMap(r *ghttp.Request) map[string]string {
filterMap := make(map[string]string)
filterSetFields := this.GetFilterSetFields()
// 如果有查詢的字符串且不為空字符串,則將它加入鍵值對
for _, filterSetField := range filterSetFields {
query := r.GetQueryString(filterSetField)
if query != "" {
filterMap[filterSetField] = query
}
}
return filterMap
}
// 獲取排序的字符串
func (this *Goods) GetOrdering(r *ghttp.Request) string {
orderingFields := this.GetOrderingSetFields()
ordering := r.GetQueryString("ordering")
// 判斷正序或者倒序
field, orderSort := GetOrderSort(ordering)
var orderingFieldResult string
// 遍歷制定的排序的字符串
// 如果獲取到的請求的字符串等於排序的字符串,那么則拼接成orm的規則
for _, orderingField := range orderingFields {
if field == orderingField {
orderingFieldResult = field + " " + orderSort
break
}
}
// 如果是空,則取默認的規則
if orderingFieldResult == "" {
orderingFieldResult = this.GetDefaultOrdering()
}
return orderingFieldResult
}
// 列表查詢
func (this *Goods) List(r *ghttp.Request) ([]*df_goods_sku.Entity, error) {
// 獲取查詢鍵值對
filterMap := this.GetFilterMap(r)
orderingField := this.GetOrdering(r)
page, page_size := GetPageData(r)
var goods []*df_goods_sku.Entity
err := g.DB().Table(df_goods_sku.Table).Where(filterMap).Order(orderingField).Page(page, page_size).Structs(&goods)
return goods, err
}
// 綁定get請求方式處理
func (this *Goods) Get(r *ghttp.Request) {
result, err := this.List(r)
if err != nil {
r.Response.Status = 500
_ = r.Response.WriteJsonExit(service.Response{
Success: false,
Message: "獲取失敗!",
Code: 500,
})
}
if result == nil {
result = []*df_goods_sku.Entity{}
}
_ = r.Response.WriteJson(service.Response{
Success: true,
Message: "獲取成功!",
Result: result,
})
}
type Good struct{}
// 獲取orm的struct對象
// 暫時這么寫,如果以后校驗對象級權限,可以增加新的函數
func (*Good) GetObject(r *ghttp.Request) (*df_goods_sku.Entity, error) {
pk := r.GetInt("id")
return df_goods_sku.FindOne("id=?", pk)
}
// 單個對象查詢
func (this *Good) Retrieve(r *ghttp.Request) (*df_goods_sku.Entity, error) {
return this.GetObject(r)
}
// 綁定get請求方法
func (this *Good) Get(r *ghttp.Request) {
good, err := this.Retrieve(r)
if err != nil {
r.Response.Status = 500
_ = r.Response.WriteJsonExit(service.Response{
Success: false,
Message: "獲取失敗!",
Code: 500,
})
}
if good == nil {
r.Response.Status = 404
_ = r.Response.WriteJsonExit(service.Response{
Success: false,
Message: "無此商品!",
Code: 404,
})
}
_ = r.Response.WriteJsonExit(service.Response{
Success: true,
Message: "獲取成功!",
Result: good,
})
}
router寫法
package router
import (
"Demo/app/api/goods"
"github.com/gogf/gf/frame/g"
)
func init() {
s := g.Server()
s.BindObjectRest("/goods", new(goods.Goods))
s.BindObjectRest("/goods/{id}", new(goods.Good))
}
具體實現, 可以參考從兩個struct的GET方法看起,都寫在了注釋里面