api文档完成

This commit is contained in:
Liujian
2024-08-30 09:55:56 +08:00
parent f3a00814a5
commit f570c8b174
75 changed files with 2206 additions and 753 deletions
+15 -7
View File
@@ -2,10 +2,11 @@ package api
import (
"context"
"github.com/APIParkLab/APIPark/module/system"
"reflect"
"github.com/eolinker/go-common/autowire"
api_dto "github.com/APIParkLab/APIPark/module/api/dto"
)
@@ -27,16 +28,23 @@ type IApiModule interface {
Delete(ctx context.Context, serviceId string, apiId string) error
// Copy 复制API
Copy(ctx context.Context, serviceId string, apiId string, dto *api_dto.CreateApi) (*api_dto.ApiSimpleDetail, error)
// ApiDocDetail 获取API文档详情
ApiDocDetail(ctx context.Context, serviceId string, apiId string) (*api_dto.ApiDocDetail, error)
// ApiProxyDetail 获取API代理详情
ApiProxyDetail(ctx context.Context, serviceId string, apiId string) (*api_dto.ApiProxyDetail, error)
// Prefix 获取API前缀
Prefix(ctx context.Context, serviceId string) (string, error)
//ExportAll(ctx context.Context) ([]*api_dto.ExportAPI, error)
}
type IExportApiModule interface {
system.IExportModule[api_dto.ExportAPI]
}
func init() {
apiModule := new(imlApiModule)
autowire.Auto[IApiModule](func() reflect.Value {
return reflect.ValueOf(new(imlApiModule))
return reflect.ValueOf(apiModule)
})
autowire.Auto[IExportApiModule](func() reflect.Value {
return reflect.ValueOf(apiModule)
})
}
+16 -11
View File
@@ -6,7 +6,7 @@ import (
"fmt"
"github.com/eolinker/go-common/utils"
"strings"
"github.com/APIParkLab/APIPark/service/api"
)
@@ -31,8 +31,7 @@ type CreateApi struct {
}
type InputProxy struct {
Path string `json:"path"`
//Upstream string `json:"upstream" aocheck:"upstream"`
Path string `json:"path"`
Timeout int `json:"timeout"`
Retry int `json:"retry"`
Headers []*Header `json:"headers"`
@@ -78,12 +77,14 @@ func (a *CreateApi) ToServiceRouter() *api.Router {
}
type EditApi struct {
Info struct {
Name *string `json:"name"`
Description *string `json:"description"`
} `json:"info"`
Proxy *InputProxy `json:"proxy"`
Doc *map[string]interface{} `json:"doc"`
Info EditInfo `json:"info"`
Proxy *InputProxy `json:"proxy"`
//Doc *map[string]interface{} `json:"doc"`
}
type EditInfo struct {
Name *string `json:"name"`
Description *string `json:"description"`
}
func ToServiceProxy(proxy *InputProxy) *api.Proxy {
@@ -97,7 +98,7 @@ func ToServiceProxy(proxy *InputProxy) *api.Proxy {
Opt: h.Opt,
}
})
return &api.Proxy{
Path: proxy.Path,
//Upstream: proxy.Upstream,
@@ -116,7 +117,7 @@ func ToServiceDocument(doc map[string]interface{}) *api.Document {
}
}
content, _ := json.Marshal(doc)
return &api.Document{
Content: string(content),
}
@@ -125,3 +126,7 @@ func ToServiceDocument(doc map[string]interface{}) *api.Document {
type ListInput struct {
Projects []string `json:"projects"`
}
type UpdateDoc struct {
Content string `json:"content"`
}
+24 -19
View File
@@ -2,9 +2,9 @@ package api_dto
import (
"encoding/json"
"github.com/eolinker/go-common/utils"
"github.com/APIParkLab/APIPark/service/api"
"github.com/eolinker/go-common/auto"
)
@@ -12,7 +12,8 @@ import (
type ApiItem struct {
Id string `json:"id"`
Name string `json:"name"`
Method string `json:"method"`
Methods []string `json:"methods"`
Protocols []string `json:"protocols"`
Path string `json:"request_path"`
Creator auto.Label `json:"creator" aolabel:"user"`
Updater auto.Label `json:"updater" aolabel:"user"`
@@ -30,8 +31,8 @@ type ApiSimpleItem struct {
type ApiDetail struct {
ApiSimpleDetail
Proxy *Proxy `json:"proxy"`
Doc map[string]interface{} `json:"doc"`
Proxy *Proxy `json:"proxy"`
//Doc map[string]interface{} `json:"doc"`
}
func GenApiSimpleDetail(api *api.Info) *ApiSimpleDetail {
@@ -40,12 +41,12 @@ func GenApiSimpleDetail(api *api.Info) *ApiSimpleDetail {
api.Match = "[]"
}
json.Unmarshal([]byte(api.Match), &match)
return &ApiSimpleDetail{
Id: api.UUID,
Name: api.Name,
Description: api.Description,
Method: api.Method,
Methods: api.Methods,
Path: api.Path,
MatchRules: match,
Creator: auto.UUID(api.Creator),
@@ -59,8 +60,9 @@ type ApiSimpleDetail struct {
Id string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Method string `json:"method"`
Methods []string `json:"methods"`
Path string `json:"path"`
Protocols []string `json:"protocols"`
MatchRules []Match `json:"match"`
Creator auto.Label `json:"creator" aolabel:"user"`
Updater auto.Label `json:"updater" aolabel:"user"`
@@ -68,21 +70,11 @@ type ApiSimpleDetail struct {
UpdateTime auto.TimeLabel `json:"update_time"`
}
type ApiDocDetail struct {
ApiSimpleDetail
Doc map[string]interface{} `json:"doc"`
}
type ApiProxyDetail struct {
ApiSimpleDetail
Proxy *Proxy `json:"proxy"`
}
func FromServiceProxy(proxy *api.Proxy) *Proxy {
if proxy == nil {
return nil
}
return &Proxy{
Path: proxy.Path,
Timeout: proxy.Timeout,
@@ -113,3 +105,16 @@ type Header struct {
Value string `json:"value"`
Opt string `json:"opt"`
}
type ExportAPI struct {
Id string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Method string `json:"method"`
Path string `json:"path"`
MatchRules []Match `json:"match"`
Service string `json:"service"`
Team string `json:"team"`
Proxy *Proxy `json:"proxy"`
Doc map[string]interface{} `json:"doc"`
}
+82 -157
View File
@@ -5,28 +5,32 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/APIParkLab/APIPark/service/universally/commit"
"strings"
"github.com/APIParkLab/APIPark/service/service"
"github.com/APIParkLab/APIPark/service/upstream"
"gorm.io/gorm"
"github.com/APIParkLab/APIPark/service/team"
"github.com/google/uuid"
"github.com/eolinker/go-common/auto"
"github.com/eolinker/go-common/utils"
"github.com/eolinker/go-common/store"
"github.com/APIParkLab/APIPark/service/api"
api_dto "github.com/APIParkLab/APIPark/module/api/dto"
)
var _ IApiModule = (*imlApiModule)(nil)
var (
_ IApiModule = (*imlApiModule)(nil)
_ IExportApiModule = (*imlApiModule)(nil)
)
var (
asServer = map[string]bool{
"as_server": true,
@@ -41,8 +45,48 @@ type imlApiModule struct {
transaction store.ITransaction `autowired:""`
}
func (i *imlApiModule) ExportAll(ctx context.Context) ([]*api_dto.ExportAPI, error) {
apiList, err := i.apiService.ListInfo(ctx)
if err != nil {
return nil, err
}
apiIds := utils.SliceToSlice(apiList, func(a *api.Info) string {
return a.UUID
})
proxyCommits, err := i.apiService.ListLatestCommitProxy(ctx, apiIds...)
if err != nil {
return nil, err
}
proxyCommitMap := utils.SliceToMap(proxyCommits, func(c *commit.Commit[api.Proxy]) string {
return c.Target
})
return utils.SliceToSlice(apiList, func(a *api.Info) *api_dto.ExportAPI {
match := make([]api_dto.Match, 0)
if a.Match == "" {
a.Match = "[]"
}
json.Unmarshal([]byte(a.Match), &match)
info := &api_dto.ExportAPI{
Id: a.UUID,
Name: a.Name,
Description: a.Description,
Path: a.Path,
MatchRules: match,
Service: a.Service,
Team: a.Team,
}
if v, ok := proxyCommitMap[a.UUID]; ok {
info.Proxy = api_dto.FromServiceProxy(v.Data)
}
return info
}), nil
}
func (i *imlApiModule) SimpleList(ctx context.Context, serviceId string) ([]*api_dto.ApiSimpleItem, error) {
list, err := i.apiService.ListForService(ctx, serviceId)
apiInfos, err := i.apiService.ListInfo(ctx, utils.SliceToSlice(list, func(s *api.API) string {
return s.UUID
@@ -50,13 +94,12 @@ func (i *imlApiModule) SimpleList(ctx context.Context, serviceId string) ([]*api
if err != nil {
return nil, err
}
out := utils.SliceToSlice(apiInfos, func(item *api.Info) *api_dto.ApiSimpleItem {
return &api_dto.ApiSimpleItem{
Id: item.UUID,
Name: item.Name,
Method: item.Method,
Path: item.Path,
Id: item.UUID,
Name: item.Name,
Path: item.Path,
}
})
return out, nil
@@ -67,12 +110,12 @@ func (i *imlApiModule) Detail(ctx context.Context, serviceId string, apiId strin
if err != nil {
return nil, err
}
detail, err := i.apiService.GetInfo(ctx, apiId)
if err != nil {
return nil, err
}
apiDetail := &api_dto.ApiDetail{
ApiSimpleDetail: *api_dto.GenApiSimpleDetail(detail),
}
@@ -83,25 +126,9 @@ func (i *imlApiModule) Detail(ctx context.Context, serviceId string, apiId strin
}
}
if proxy != nil {
apiDetail.Proxy = api_dto.FromServiceProxy(proxy.Data)
}
document, err := i.apiService.LatestDocument(ctx, apiId)
if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
}
if document != nil {
doc := make(map[string]interface{})
err = json.Unmarshal([]byte(document.Data.Content), &doc)
if err != nil {
return nil, err
}
apiDetail.Doc = doc
}
return apiDetail, nil
}
@@ -110,12 +137,12 @@ func (i *imlApiModule) SimpleDetail(ctx context.Context, serviceId string, apiId
if err != nil {
return nil, err
}
detail, err := i.apiService.GetInfo(ctx, apiId)
if err != nil {
return nil, err
}
return api_dto.GenApiSimpleDetail(detail), nil
}
@@ -124,7 +151,7 @@ func (i *imlApiModule) Search(ctx context.Context, keyword string, serviceId str
if err != nil {
return nil, err
}
list, err := i.apiService.Search(ctx, keyword, map[string]interface{}{
"service": serviceId,
})
@@ -144,7 +171,8 @@ func (i *imlApiModule) Search(ctx context.Context, keyword string, serviceId str
return &api_dto.ApiItem{
Id: item.UUID,
Name: item.Name,
Method: item.Method,
Methods: item.Methods,
Protocols: item.Protocols,
Path: item.Path,
Creator: auto.UUID(item.Creator),
Updater: auto.UUID(item.Updater),
@@ -153,7 +181,7 @@ func (i *imlApiModule) Search(ctx context.Context, keyword string, serviceId str
CanDelete: true,
}
})
return out, nil
}
@@ -162,7 +190,7 @@ func (i *imlApiModule) SimpleSearch(ctx context.Context, keyword string, service
if err != nil {
return nil, err
}
list, err := i.apiService.Search(ctx, keyword, map[string]interface{}{
"service": serviceId,
})
@@ -177,10 +205,10 @@ func (i *imlApiModule) SimpleSearch(ctx context.Context, keyword string, service
}
out := utils.SliceToSlice(apiInfos, func(item *api.Info) *api_dto.ApiSimpleItem {
return &api_dto.ApiSimpleItem{
Id: item.UUID,
Name: item.Name,
Method: item.Method,
Path: item.Path,
Id: item.UUID,
Name: item.Name,
//Methods: item.Methods,
Path: item.Path,
}
})
return out, nil
@@ -203,7 +231,7 @@ func (i *imlApiModule) Create(ctx context.Context, serviceId string, dto *api_dt
if err != nil {
return err
}
path := fmt.Sprintf("%s%s", prefix, dto.Path)
err = i.apiService.Exist(ctx, "", &api.ExistAPI{Path: dto.Path, Method: dto.Method})
if err != nil {
@@ -214,11 +242,7 @@ func (i *imlApiModule) Create(ctx context.Context, serviceId string, dto *api_dt
if err != nil {
return err
}
err = i.apiService.SaveDocument(ctx, dto.Id, api_dto.ToServiceDocument(nil))
if err != nil {
return err
}
match, _ := json.Marshal(dto.MatchRules)
return i.apiService.Create(ctx, &api.CreateAPI{
UUID: dto.Id,
@@ -229,7 +253,6 @@ func (i *imlApiModule) Create(ctx context.Context, serviceId string, dto *api_dt
Method: dto.Method,
Path: path,
Match: string(match),
//Upstream: proxy.Upstream,
})
})
if err != nil {
@@ -243,7 +266,7 @@ func (i *imlApiModule) Edit(ctx context.Context, serviceId string, apiId string,
if err != nil {
return nil, err
}
err = i.transaction.Transaction(ctx, func(ctx context.Context) error {
var up *string
if dto.Proxy != nil {
@@ -251,9 +274,6 @@ func (i *imlApiModule) Edit(ctx context.Context, serviceId string, apiId string,
if err != nil {
return err
}
//if dto.Proxy.Upstream != "" {
// up = &dto.Proxy.Upstream
//}
}
err = i.apiService.Save(ctx, apiId, &api.EditAPI{
Name: dto.Info.Name,
@@ -263,15 +283,9 @@ func (i *imlApiModule) Edit(ctx context.Context, serviceId string, apiId string,
if err != nil {
return err
}
if dto.Doc != nil {
err = i.apiService.SaveDocument(ctx, apiId, api_dto.ToServiceDocument(*dto.Doc))
if err != nil {
return err
}
}
return nil
})
if err != nil {
return nil, err
@@ -308,13 +322,13 @@ func (i *imlApiModule) Copy(ctx context.Context, serviceId string, apiId string,
if err != nil {
return err
}
path := fmt.Sprintf("%s/%s", strings.TrimSuffix(prefix, "/"), strings.TrimPrefix(dto.Path, "/"))
err = i.apiService.Exist(ctx, serviceId, &api.ExistAPI{Path: path, Method: dto.Method})
if err != nil {
return err
}
proxy, err := i.apiService.LatestProxy(ctx, oldApi.UUID)
if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
@@ -327,21 +341,8 @@ func (i *imlApiModule) Copy(ctx context.Context, serviceId string, apiId string,
if err != nil {
return err
}
//upstreamId = proxy.Data.Upstream
}
doc, err := i.apiService.LatestDocument(ctx, oldApi.UUID)
if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
}
if doc != nil {
err = i.apiService.SaveDocument(ctx, dto.Id, doc.Data)
if err != nil {
return err
}
}
match, _ := json.Marshal(dto.MatchRules)
return i.apiService.Create(ctx, &api.CreateAPI{
UUID: dto.Id,
@@ -351,9 +352,8 @@ func (i *imlApiModule) Copy(ctx context.Context, serviceId string, apiId string,
Method: dto.Method,
Path: path,
Match: string(match),
//Upstream: upstreamId,
})
})
if err != nil {
return nil, err
@@ -361,87 +361,12 @@ func (i *imlApiModule) Copy(ctx context.Context, serviceId string, apiId string,
return i.SimpleDetail(ctx, serviceId, dto.Id)
}
func (i *imlApiModule) ApiDocDetail(ctx context.Context, serviceId string, apiId string) (*api_dto.ApiDocDetail, error) {
_, err := i.serviceService.Check(ctx, serviceId, asServer)
if err != nil {
return nil, err
}
apiBase, err := i.apiService.Get(ctx, apiId)
if err != nil {
return nil, err
}
if apiBase.IsDelete {
return nil, errors.New("api is delete")
}
detail, err := i.apiService.GetInfo(ctx, apiBase.UUID)
if err != nil {
return nil, err
}
document, err := i.apiService.LatestDocument(ctx, apiId)
if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
}
var doc map[string]interface{}
if document != nil {
doc = make(map[string]interface{})
err = json.Unmarshal([]byte(document.Data.Content), &doc)
if err != nil {
return nil, err
}
}
return &api_dto.ApiDocDetail{
ApiSimpleDetail: *api_dto.GenApiSimpleDetail(detail),
Doc: doc,
}, nil
}
func (i *imlApiModule) ApiProxyDetail(ctx context.Context, serviceId string, apiId string) (*api_dto.ApiProxyDetail, error) {
_, err := i.serviceService.Check(ctx, serviceId, asServer)
if err != nil {
return nil, err
}
apiBase, err := i.apiService.Get(ctx, apiId)
if err != nil {
return nil, err
}
if apiBase.IsDelete {
return nil, errors.New("api is delete")
}
if apiBase.Service != serviceId {
return nil, errors.New("api is not in project")
}
detail, err := i.apiService.GetInfo(ctx, apiId)
if err != nil {
return nil, err
}
apiDetail := &api_dto.ApiProxyDetail{
ApiSimpleDetail: *api_dto.GenApiSimpleDetail(detail),
}
proxy, err := i.apiService.LatestProxy(ctx, apiId)
if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
}
if proxy != nil {
apiDetail.Proxy = api_dto.FromServiceProxy(proxy.Data)
}
return apiDetail, nil
}
func (i *imlApiModule) Prefix(ctx context.Context, serviceId string) (string, error) {
pInfo, err := i.serviceService.Check(ctx, serviceId, asServer)
if err != nil {
return "", err
}
if pInfo.Prefix != "" {
if pInfo.Prefix[0] != '/' {
pInfo.Prefix = fmt.Sprintf("/%s", strings.TrimSuffix(pInfo.Prefix, "/"))