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方法看起,都写在了注释里面