mirror of
https://github.com/APIParkLab/APIPark.git
synced 2026-06-26 16:01:56 +08:00
首次提交APIPark代码,面向开源
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
|
||||
"github.com/eolinker/go-common/autowire"
|
||||
|
||||
api_dto "github.com/APIParkLab/APIPark/module/api/dto"
|
||||
)
|
||||
|
||||
type IApiModule interface {
|
||||
// Detail 获取API详情
|
||||
Detail(ctx context.Context, serviceId string, apiId string) (*api_dto.ApiDetail, error)
|
||||
// SimpleDetail 获取API简要详情
|
||||
SimpleDetail(ctx context.Context, serviceId string, apiId string) (*api_dto.ApiSimpleDetail, error)
|
||||
// Search 获取API列表
|
||||
Search(ctx context.Context, keyword string, serviceId string) ([]*api_dto.ApiItem, error)
|
||||
// SimpleSearch 获取API简要列表
|
||||
SimpleSearch(ctx context.Context, keyword string, serviceId string) ([]*api_dto.ApiSimpleItem, error)
|
||||
SimpleList(ctx context.Context, serviceId string) ([]*api_dto.ApiSimpleItem, error)
|
||||
// Create 创建API
|
||||
Create(ctx context.Context, serviceId string, dto *api_dto.CreateApi) (*api_dto.ApiSimpleDetail, error)
|
||||
// Edit 编辑API
|
||||
Edit(ctx context.Context, serviceId string, apiId string, dto *api_dto.EditApi) (*api_dto.ApiSimpleDetail, error)
|
||||
// Delete 删除API
|
||||
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)
|
||||
}
|
||||
|
||||
func init() {
|
||||
autowire.Auto[IApiModule](func() reflect.Value {
|
||||
return reflect.ValueOf(new(imlApiModule))
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package api_dto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/eolinker/go-common/utils"
|
||||
"strings"
|
||||
|
||||
"github.com/APIParkLab/APIPark/service/api"
|
||||
)
|
||||
|
||||
var validMethods = map[string]struct{}{
|
||||
"GET": {},
|
||||
"POST": {},
|
||||
"PUT": {},
|
||||
"DELETE": {},
|
||||
"PATCH": {},
|
||||
"HEAD": {},
|
||||
"OPTIONS": {},
|
||||
}
|
||||
|
||||
type CreateApi struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
Method string `json:"method"`
|
||||
Description string `json:"description"`
|
||||
MatchRules []Match `json:"match"`
|
||||
Proxy *InputProxy `json:"proxy"`
|
||||
}
|
||||
|
||||
type InputProxy struct {
|
||||
Path string `json:"path"`
|
||||
//Upstream string `json:"upstream" aocheck:"upstream"`
|
||||
Timeout int `json:"timeout"`
|
||||
Retry int `json:"retry"`
|
||||
Headers []*Header `json:"headers"`
|
||||
Extends map[string]any `json:"extends"`
|
||||
Plugins map[string]api.PluginSetting `json:"plugins"`
|
||||
}
|
||||
type Match struct {
|
||||
Position string `json:"position"`
|
||||
MatchType string `json:"match_type"`
|
||||
Key string `json:"key"`
|
||||
Pattern string `json:"pattern"`
|
||||
}
|
||||
|
||||
func (a *CreateApi) Validate() error {
|
||||
if a.Id == "" {
|
||||
return errors.New("id is null")
|
||||
}
|
||||
if a.Name == "" {
|
||||
return errors.New("name is null")
|
||||
}
|
||||
a.Path = fmt.Sprintf("/%s", strings.TrimPrefix(a.Path, "/"))
|
||||
a.Method = strings.ToUpper(a.Method)
|
||||
if _, ok := validMethods[a.Method]; !ok {
|
||||
return fmt.Errorf("method(%s) is invalid", a.Method)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *CreateApi) ToServiceRouter() *api.Router {
|
||||
router := &api.Router{
|
||||
Method: a.Method,
|
||||
Path: a.Path,
|
||||
}
|
||||
for _, match := range a.MatchRules {
|
||||
router.MatchRules = append(router.MatchRules, &api.Match{
|
||||
Position: match.Position,
|
||||
MatchType: match.MatchType,
|
||||
Key: match.Key,
|
||||
Pattern: match.Pattern,
|
||||
})
|
||||
}
|
||||
return 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"`
|
||||
}
|
||||
|
||||
func ToServiceProxy(proxy *InputProxy) *api.Proxy {
|
||||
if proxy == nil {
|
||||
return &api.Proxy{}
|
||||
}
|
||||
headers := utils.SliceToSlice(proxy.Headers, func(h *Header) *api.Header {
|
||||
return &api.Header{
|
||||
Key: h.Key,
|
||||
Value: h.Value,
|
||||
Opt: h.Opt,
|
||||
}
|
||||
})
|
||||
|
||||
return &api.Proxy{
|
||||
Path: proxy.Path,
|
||||
//Upstream: proxy.Upstream,
|
||||
Timeout: proxy.Timeout,
|
||||
Retry: proxy.Retry,
|
||||
Extends: proxy.Extends,
|
||||
Plugins: proxy.Plugins,
|
||||
Headers: headers,
|
||||
}
|
||||
}
|
||||
|
||||
func ToServiceDocument(doc map[string]interface{}) *api.Document {
|
||||
if doc == nil {
|
||||
return &api.Document{
|
||||
Content: "{}",
|
||||
}
|
||||
}
|
||||
content, _ := json.Marshal(doc)
|
||||
|
||||
return &api.Document{
|
||||
Content: string(content),
|
||||
}
|
||||
}
|
||||
|
||||
type ListInput struct {
|
||||
Projects []string `json:"projects"`
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package api_dto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/eolinker/go-common/utils"
|
||||
|
||||
"github.com/APIParkLab/APIPark/service/api"
|
||||
"github.com/eolinker/go-common/auto"
|
||||
)
|
||||
|
||||
type ApiItem struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Method string `json:"method"`
|
||||
Path string `json:"request_path"`
|
||||
Creator auto.Label `json:"creator" aolabel:"user"`
|
||||
Updater auto.Label `json:"updater" aolabel:"user"`
|
||||
CreateTime auto.TimeLabel `json:"create_time"`
|
||||
UpdateTime auto.TimeLabel `json:"update_time"`
|
||||
CanDelete bool `json:"can_delete"`
|
||||
}
|
||||
|
||||
type ApiSimpleItem struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Method string `json:"method"`
|
||||
Path string `json:"request_path"`
|
||||
}
|
||||
|
||||
type ApiDetail struct {
|
||||
ApiSimpleDetail
|
||||
Proxy *Proxy `json:"proxy"`
|
||||
Doc map[string]interface{} `json:"doc"`
|
||||
}
|
||||
|
||||
func GenApiSimpleDetail(api *api.Info) *ApiSimpleDetail {
|
||||
match := make([]Match, 0)
|
||||
if api.Match == "" {
|
||||
api.Match = "[]"
|
||||
}
|
||||
json.Unmarshal([]byte(api.Match), &match)
|
||||
|
||||
return &ApiSimpleDetail{
|
||||
Id: api.UUID,
|
||||
Name: api.Name,
|
||||
Description: api.Description,
|
||||
Method: api.Method,
|
||||
Path: api.Path,
|
||||
MatchRules: match,
|
||||
Creator: auto.UUID(api.Creator),
|
||||
Updater: auto.UUID(api.Updater),
|
||||
CreateTime: auto.TimeLabel(api.CreateAt),
|
||||
UpdateTime: auto.TimeLabel(api.UpdateAt),
|
||||
}
|
||||
}
|
||||
|
||||
type ApiSimpleDetail 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"`
|
||||
Creator auto.Label `json:"creator" aolabel:"user"`
|
||||
Updater auto.Label `json:"updater" aolabel:"user"`
|
||||
CreateTime auto.TimeLabel `json:"create_time"`
|
||||
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,
|
||||
Retry: proxy.Retry,
|
||||
Headers: utils.SliceToSlice(proxy.Headers, func(header *api.Header) *Header {
|
||||
return &Header{
|
||||
Key: header.Key,
|
||||
Value: header.Value,
|
||||
Opt: header.Opt,
|
||||
}
|
||||
}),
|
||||
Extends: proxy.Extends,
|
||||
Plugins: proxy.Plugins,
|
||||
}
|
||||
}
|
||||
|
||||
type Proxy struct {
|
||||
Path string `json:"path"`
|
||||
Timeout int `json:"timeout"`
|
||||
Retry int `json:"retry"`
|
||||
Headers []*Header `json:"headers"`
|
||||
Extends map[string]any `json:"extends"`
|
||||
Plugins map[string]api.PluginSetting `json:"plugins"`
|
||||
}
|
||||
|
||||
type Header struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
Opt string `json:"opt"`
|
||||
}
|
||||
@@ -0,0 +1,451 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"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 (
|
||||
asServer = map[string]bool{
|
||||
"as_server": true,
|
||||
}
|
||||
)
|
||||
|
||||
type imlApiModule struct {
|
||||
teamService team.ITeamService `autowired:""`
|
||||
serviceService service.IServiceService `autowired:""`
|
||||
apiService api.IAPIService `autowired:""`
|
||||
upstreamService upstream.IUpstreamService `autowired:""`
|
||||
transaction store.ITransaction `autowired:""`
|
||||
}
|
||||
|
||||
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
|
||||
})...)
|
||||
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,
|
||||
}
|
||||
})
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (i *imlApiModule) Detail(ctx context.Context, serviceId string, apiId string) (*api_dto.ApiDetail, error) {
|
||||
_, err := i.serviceService.Check(ctx, serviceId, asServer)
|
||||
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),
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (i *imlApiModule) SimpleDetail(ctx context.Context, serviceId string, apiId string) (*api_dto.ApiSimpleDetail, error) {
|
||||
_, err := i.serviceService.Check(ctx, serviceId, asServer)
|
||||
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
|
||||
}
|
||||
|
||||
func (i *imlApiModule) Search(ctx context.Context, keyword string, serviceId string) ([]*api_dto.ApiItem, error) {
|
||||
_, err := i.serviceService.Check(ctx, serviceId, asServer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list, err := i.apiService.Search(ctx, keyword, map[string]interface{}{
|
||||
"service": serviceId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
apiInfos, err := i.apiService.ListInfo(ctx, utils.SliceToSlice(list, func(s *api.API) string {
|
||||
return s.UUID
|
||||
})...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
utils.Sort(apiInfos, func(a, b *api.Info) bool {
|
||||
return a.UpdateAt.After(b.UpdateAt)
|
||||
})
|
||||
out := utils.SliceToSlice(apiInfos, func(item *api.Info) *api_dto.ApiItem {
|
||||
return &api_dto.ApiItem{
|
||||
Id: item.UUID,
|
||||
Name: item.Name,
|
||||
Method: item.Method,
|
||||
Path: item.Path,
|
||||
Creator: auto.UUID(item.Creator),
|
||||
Updater: auto.UUID(item.Updater),
|
||||
CreateTime: auto.TimeLabel(item.CreateAt),
|
||||
UpdateTime: auto.TimeLabel(item.UpdateAt),
|
||||
CanDelete: true,
|
||||
}
|
||||
})
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (i *imlApiModule) SimpleSearch(ctx context.Context, keyword string, serviceId string) ([]*api_dto.ApiSimpleItem, error) {
|
||||
_, err := i.serviceService.Check(ctx, serviceId, asServer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list, err := i.apiService.Search(ctx, keyword, map[string]interface{}{
|
||||
"service": serviceId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
apiInfos, err := i.apiService.ListInfo(ctx, utils.SliceToSlice(list, func(s *api.API) string {
|
||||
return s.UUID
|
||||
})...)
|
||||
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,
|
||||
}
|
||||
})
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (i *imlApiModule) Create(ctx context.Context, serviceId string, dto *api_dto.CreateApi) (*api_dto.ApiSimpleDetail, error) {
|
||||
info, err := i.serviceService.Check(ctx, serviceId, asServer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
prefix, err := i.Prefix(ctx, serviceId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = i.transaction.Transaction(ctx, func(ctx context.Context) error {
|
||||
if dto.Id == "" {
|
||||
dto.Id = uuid.New().String()
|
||||
}
|
||||
err = dto.Validate()
|
||||
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 {
|
||||
return fmt.Errorf("api path %s,method: %s already exist", dto.Path, dto.Method)
|
||||
}
|
||||
proxy := api_dto.ToServiceProxy(dto.Proxy)
|
||||
err = i.apiService.SaveProxy(ctx, dto.Id, proxy)
|
||||
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,
|
||||
Name: dto.Name,
|
||||
Description: dto.Description,
|
||||
Service: serviceId,
|
||||
Team: info.Team,
|
||||
Method: dto.Method,
|
||||
Path: path,
|
||||
Match: string(match),
|
||||
//Upstream: proxy.Upstream,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i.SimpleDetail(ctx, serviceId, dto.Id)
|
||||
}
|
||||
|
||||
func (i *imlApiModule) Edit(ctx context.Context, serviceId string, apiId string, dto *api_dto.EditApi) (*api_dto.ApiSimpleDetail, error) {
|
||||
_, err := i.serviceService.Check(ctx, serviceId, asServer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = i.transaction.Transaction(ctx, func(ctx context.Context) error {
|
||||
var up *string
|
||||
if dto.Proxy != nil {
|
||||
err = i.apiService.SaveProxy(ctx, apiId, api_dto.ToServiceProxy(dto.Proxy))
|
||||
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,
|
||||
Description: dto.Info.Description,
|
||||
Upstream: up,
|
||||
})
|
||||
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
|
||||
}
|
||||
return i.SimpleDetail(ctx, serviceId, apiId)
|
||||
}
|
||||
|
||||
func (i *imlApiModule) Delete(ctx context.Context, serviceId string, apiId string) error {
|
||||
_, err := i.serviceService.Check(ctx, serviceId, asServer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return i.apiService.Delete(ctx, apiId)
|
||||
}
|
||||
|
||||
func (i *imlApiModule) Copy(ctx context.Context, serviceId string, apiId string, dto *api_dto.CreateApi) (*api_dto.ApiSimpleDetail, error) {
|
||||
info, err := i.serviceService.Check(ctx, serviceId, asServer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oldApi, err := i.apiService.Get(ctx, apiId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
prefix, err := i.Prefix(ctx, serviceId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = i.transaction.Transaction(ctx, func(ctx context.Context) error {
|
||||
if dto.Id == "" {
|
||||
dto.Id = uuid.New().String()
|
||||
}
|
||||
err = dto.Validate()
|
||||
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) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
//upstreamId := ""
|
||||
if proxy != nil {
|
||||
err = i.apiService.SaveProxy(ctx, dto.Id, proxy.Data)
|
||||
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,
|
||||
Name: dto.Name,
|
||||
Service: serviceId,
|
||||
Team: info.Team,
|
||||
Method: dto.Method,
|
||||
Path: path,
|
||||
Match: string(match),
|
||||
//Upstream: upstreamId,
|
||||
})
|
||||
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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, "/"))
|
||||
}
|
||||
}
|
||||
return strings.TrimSuffix(pInfo.Prefix, "/"), nil
|
||||
}
|
||||
Reference in New Issue
Block a user