Deduplicate server JSON structs between publisher and registry (#318)
<!-- Provide a brief summary of your changes --> ## Motivation and Context <!-- Why is this change needed? What problem does it solve? --> The following PR eliminates duplicate struct definitions by migrating the publisher tool to use canonical types from pkg/model, creating a single source of truth across the codebase. The publisher tool previously had its own copies of structs that were duplicated, ie. ServerJSON, Package, Repository, VersionDetail, EnvironmentVariable, RuntimeArgument and a few others which was not optimal **Changes in the PR:** - Refactored the structs to single canonical types located at pkg/model - Refactor the implementation to use/build canonical structures directly - Remove all duplicate definitions (5 structs eliminated) - Publisher now uses model.ServerJSON, model.Package, model.Repository, etc. - Renamed some of the structs to better reflect their use case, i.e. ServerJSON instead of ServerDetail - Fixes an issue where the Remote property was missing from the previous publisher copy of the Server **Benefits:** - Single source of truth - Schema changes in one place - Type safety - Compiler catches mismatches - Enhanced validation - Field constraints and bson tags - Zero breaking changes - Same CLI interface and JSON output - Future-proof - New canonical fields automatically available Supersedes: #217 and #240 ## How Has This Been Tested? <!-- Have you tested this in a real application? Which scenarios were tested? --> Locally ## Breaking Changes <!-- Will users need to update their code or configurations? --> No ## Types of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [ ] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [ ] My code follows the repository's style guidelines - [ ] New and existing tests pass locally - [ ] I have added appropriate error handling - [ ] I have added or updated documentation as needed ## Additional context <!-- Add any other context, implementation notes, or design decisions --> --------- Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
This commit is contained in:
parent
9d04671ee3
commit
099a2d702e
4 changed files with 1280 additions and 1408 deletions
|
|
@ -6,7 +6,9 @@ import (
|
|||
|
||||
"github.com/google/uuid"
|
||||
"github.com/modelcontextprotocol/registry/internal/database"
|
||||
"github.com/modelcontextprotocol/registry/internal/model"
|
||||
"github.com/modelcontextprotocol/registry/internal/validators"
|
||||
apiv1 "github.com/modelcontextprotocol/registry/pkg/api/v1"
|
||||
"github.com/modelcontextprotocol/registry/pkg/model"
|
||||
)
|
||||
|
||||
// fakeRegistryService implements RegistryService interface with an in-memory database
|
||||
|
|
@ -16,8 +18,8 @@ type fakeRegistryService struct {
|
|||
|
||||
// NewFakeRegistryService creates a new fake registry service with pre-populated data
|
||||
func NewFakeRegistryService() RegistryService {
|
||||
// Sample registry entries with updated model structure using ServerDetail
|
||||
serverDetails := []*model.ServerDetail{
|
||||
// Sample registry entries with updated model structure using ServerJSON
|
||||
serverDetails := []*model.ServerJSON{
|
||||
{
|
||||
Name: "bluegreen/mcp-server",
|
||||
Description: "A dummy MCP registry for testing",
|
||||
|
|
@ -57,7 +59,7 @@ func NewFakeRegistryService() RegistryService {
|
|||
}
|
||||
|
||||
// Create a new in-memory database using registry metadata IDs
|
||||
serverDetailMap := make(map[string]*model.ServerDetail)
|
||||
serverDetailMap := make(map[string]*model.ServerJSON)
|
||||
for _, entry := range serverDetails {
|
||||
registryID := uuid.New().String() // Generate registry metadata ID
|
||||
serverDetailMap[registryID] = entry
|
||||
|
|
@ -69,7 +71,7 @@ func NewFakeRegistryService() RegistryService {
|
|||
}
|
||||
|
||||
// List retrieves servers with extension wrapper format
|
||||
func (s *fakeRegistryService) List(cursor string, limit int) ([]model.ServerResponse, string, error) {
|
||||
func (s *fakeRegistryService) List(cursor string, limit int) ([]apiv1.ServerRecord, string, error) {
|
||||
// Create a timeout context for the database operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
|
@ -80,17 +82,17 @@ func (s *fakeRegistryService) List(cursor string, limit int) ([]model.ServerResp
|
|||
return nil, "", err
|
||||
}
|
||||
|
||||
// Convert ServerRecord to ServerResponse format
|
||||
result := make([]model.ServerResponse, len(serverRecords))
|
||||
// Return ServerRecords directly (they're now the same as ServerResponse)
|
||||
result := make([]apiv1.ServerRecord, len(serverRecords))
|
||||
for i, record := range serverRecords {
|
||||
result[i] = record.ToServerResponse()
|
||||
result[i] = *record
|
||||
}
|
||||
|
||||
return result, nextCursor, nil
|
||||
}
|
||||
|
||||
// GetByID retrieves a specific server by its registry metadata ID in extension wrapper format
|
||||
func (s *fakeRegistryService) GetByID(id string) (*model.ServerResponse, error) {
|
||||
func (s *fakeRegistryService) GetByID(id string) (*apiv1.ServerRecord, error) {
|
||||
// Create a timeout context for the database operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
|
@ -101,33 +103,32 @@ func (s *fakeRegistryService) GetByID(id string) (*model.ServerResponse, error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Convert ServerRecord to ServerResponse format
|
||||
response := serverRecord.ToServerResponse()
|
||||
return &response, nil
|
||||
// Return ServerRecord directly (it's now the same as ServerResponse)
|
||||
return serverRecord, nil
|
||||
}
|
||||
|
||||
// Publish publishes a server with separated extensions
|
||||
func (s *fakeRegistryService) Publish(req model.PublishRequest) (*model.ServerResponse, error) {
|
||||
func (s *fakeRegistryService) Publish(req apiv1.PublishRequest) (*apiv1.ServerRecord, error) {
|
||||
// Create a timeout context for the database operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Validate the request
|
||||
if err := model.ValidatePublisherExtensions(req); err != nil {
|
||||
if err := validators.ValidatePublisherExtensions(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Validate server name exists
|
||||
if _, err := model.ParseServerName(req.Server); err != nil {
|
||||
if _, err := validators.ParseServerName(req.Server); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Extract publisher extensions from request
|
||||
publisherExtensions := model.ExtractPublisherExtensions(req)
|
||||
publisherExtensions := validators.ExtractPublisherExtensions(req)
|
||||
|
||||
// Create registry metadata for fake service (always marks as latest)
|
||||
now := time.Now()
|
||||
registryMetadata := model.RegistryMetadata{
|
||||
registryMetadata := apiv1.RegistryExtensions{
|
||||
ID: uuid.New().String(),
|
||||
PublishedAt: now,
|
||||
UpdatedAt: now,
|
||||
|
|
@ -141,28 +142,27 @@ func (s *fakeRegistryService) Publish(req model.PublishRequest) (*model.ServerRe
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Convert ServerRecord to ServerResponse format
|
||||
response := serverRecord.ToServerResponse()
|
||||
return &response, nil
|
||||
// Return ServerRecord directly (it's now the same as ServerResponse)
|
||||
return serverRecord, nil
|
||||
}
|
||||
|
||||
// EditServer updates an existing server with new details (admin operation)
|
||||
func (s *fakeRegistryService) EditServer(id string, req model.PublishRequest) (*model.ServerResponse, error) {
|
||||
func (s *fakeRegistryService) EditServer(id string, req apiv1.PublishRequest) (*apiv1.ServerRecord, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Validate the request
|
||||
if err := model.ValidatePublisherExtensions(req); err != nil {
|
||||
if err := validators.ValidatePublisherExtensions(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Validate server name exists and format
|
||||
if _, err := model.ParseServerName(req.Server); err != nil {
|
||||
if _, err := validators.ParseServerName(req.Server); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Extract publisher extensions from request
|
||||
publisherExtensions := model.ExtractPublisherExtensions(req)
|
||||
publisherExtensions := validators.ExtractPublisherExtensions(req)
|
||||
|
||||
// Update server in database
|
||||
serverRecord, err := s.db.UpdateServer(ctx, id, req.Server, publisherExtensions)
|
||||
|
|
@ -170,9 +170,8 @@ func (s *fakeRegistryService) EditServer(id string, req model.PublishRequest) (*
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Convert ServerRecord to ServerResponse format
|
||||
response := serverRecord.ToServerResponse()
|
||||
return &response, nil
|
||||
// Return ServerRecord directly (it's now the same as ServerResponse)
|
||||
return serverRecord, nil
|
||||
}
|
||||
|
||||
// Close closes the in-memory database connection
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ import (
|
|||
|
||||
"github.com/google/uuid"
|
||||
"github.com/modelcontextprotocol/registry/internal/database"
|
||||
"github.com/modelcontextprotocol/registry/internal/model"
|
||||
"github.com/modelcontextprotocol/registry/internal/validators"
|
||||
apiv1 "github.com/modelcontextprotocol/registry/pkg/api/v1"
|
||||
"github.com/modelcontextprotocol/registry/pkg/model"
|
||||
)
|
||||
|
||||
const maxServerVersionsPerServer = 10000
|
||||
|
|
@ -28,7 +30,7 @@ func NewRegistryServiceWithDB(db database.Database) RegistryService {
|
|||
}
|
||||
|
||||
// List returns registry entries with cursor-based pagination in extension wrapper format
|
||||
func (s *registryServiceImpl) List(cursor string, limit int) ([]model.ServerResponse, string, error) {
|
||||
func (s *registryServiceImpl) List(cursor string, limit int) ([]apiv1.ServerRecord, string, error) {
|
||||
// Create a timeout context for the database operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
|
@ -44,17 +46,17 @@ func (s *registryServiceImpl) List(cursor string, limit int) ([]model.ServerResp
|
|||
return nil, "", err
|
||||
}
|
||||
|
||||
// Convert ServerRecord to ServerResponse format
|
||||
result := make([]model.ServerResponse, len(serverRecords))
|
||||
// Return ServerRecords directly (they're now the same as ServerResponse)
|
||||
result := make([]apiv1.ServerRecord, len(serverRecords))
|
||||
for i, record := range serverRecords {
|
||||
result[i] = record.ToServerResponse()
|
||||
result[i] = *record
|
||||
}
|
||||
|
||||
return result, nextCursor, nil
|
||||
}
|
||||
|
||||
// GetByID retrieves a specific server by its registry metadata ID in extension wrapper format
|
||||
func (s *registryServiceImpl) GetByID(id string) (*model.ServerResponse, error) {
|
||||
func (s *registryServiceImpl) GetByID(id string) (*apiv1.ServerRecord, error) {
|
||||
// Create a timeout context for the database operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
|
@ -65,9 +67,8 @@ func (s *registryServiceImpl) GetByID(id string) (*model.ServerResponse, error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Convert ServerRecord to ServerResponse format
|
||||
response := serverRecord.ToServerResponse()
|
||||
return &response, nil
|
||||
// Return ServerRecord directly (it's now the same as ServerResponse)
|
||||
return serverRecord, nil
|
||||
}
|
||||
|
||||
// validateMCPBPackage validates MCPB packages
|
||||
|
|
@ -126,18 +127,18 @@ func validatePackage(pkg *model.Package) error {
|
|||
}
|
||||
|
||||
// Publish publishes a server with separated extensions
|
||||
func (s *registryServiceImpl) Publish(req model.PublishRequest) (*model.ServerResponse, error) {
|
||||
func (s *registryServiceImpl) Publish(req apiv1.PublishRequest) (*apiv1.ServerRecord, error) {
|
||||
// Create a timeout context for the database operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Validate the request
|
||||
if err := model.ValidatePublisherExtensions(req); err != nil {
|
||||
if err := validators.ValidatePublisherExtensions(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Validate server name exists and format
|
||||
if _, err := model.ParseServerName(req.Server); err != nil {
|
||||
if _, err := validators.ParseServerName(req.Server); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +150,7 @@ func (s *registryServiceImpl) Publish(req model.PublishRequest) (*model.ServerRe
|
|||
}
|
||||
|
||||
// Validate reverse-DNS namespace matching for remote URLs
|
||||
if err := model.ValidateRemoteNamespaceMatch(req.Server); err != nil {
|
||||
if err := validators.ValidateRemoteNamespaceMatch(req.Server); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -179,16 +180,16 @@ func (s *registryServiceImpl) Publish(req model.PublishRequest) (*model.ServerRe
|
|||
|
||||
// Check all existing versions for duplicates and determine if new version should be latest
|
||||
for _, server := range existingServers {
|
||||
existingVersion := server.ServerJSON.VersionDetail.Version
|
||||
existingVersion := server.Server.VersionDetail.Version
|
||||
|
||||
// Early exit: check for duplicate version
|
||||
if existingVersion == newVersion {
|
||||
return nil, database.ErrInvalidVersion
|
||||
}
|
||||
|
||||
if server.RegistryMetadata.IsLatest {
|
||||
existingLatestID = server.RegistryMetadata.ID
|
||||
existingTime, _ := time.Parse(time.RFC3339, server.RegistryMetadata.ReleaseDate)
|
||||
if server.XIOModelContextProtocolRegistry.IsLatest {
|
||||
existingLatestID = server.XIOModelContextProtocolRegistry.ID
|
||||
existingTime, _ := time.Parse(time.RFC3339, server.XIOModelContextProtocolRegistry.ReleaseDate)
|
||||
|
||||
// Compare versions using the proper versioning strategy
|
||||
comparison := CompareVersions(newVersion, existingVersion, currentTime, existingTime)
|
||||
|
|
@ -200,10 +201,10 @@ func (s *registryServiceImpl) Publish(req model.PublishRequest) (*model.ServerRe
|
|||
}
|
||||
|
||||
// Extract publisher extensions from request
|
||||
publisherExtensions := model.ExtractPublisherExtensions(req)
|
||||
publisherExtensions := validators.ExtractPublisherExtensions(req)
|
||||
|
||||
// Create registry metadata with service-determined values
|
||||
registryMetadata := model.RegistryMetadata{
|
||||
registryMetadata := apiv1.RegistryExtensions{
|
||||
ID: uuid.New().String(),
|
||||
PublishedAt: currentTime,
|
||||
UpdatedAt: currentTime,
|
||||
|
|
@ -225,13 +226,12 @@ func (s *registryServiceImpl) Publish(req model.PublishRequest) (*model.ServerRe
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Convert ServerRecord to ServerResponse format
|
||||
response := serverRecord.ToServerResponse()
|
||||
return &response, nil
|
||||
// Return ServerRecord directly (it's now the same as ServerResponse)
|
||||
return serverRecord, nil
|
||||
}
|
||||
|
||||
// validateNoDuplicateRemoteURLs checks that no other server is using the same remote URLs
|
||||
func (s *registryServiceImpl) validateNoDuplicateRemoteURLs(ctx context.Context, serverDetail model.ServerDetail) error {
|
||||
func (s *registryServiceImpl) validateNoDuplicateRemoteURLs(ctx context.Context, serverDetail model.ServerJSON) error {
|
||||
// Check each remote URL in the new server for conflicts
|
||||
for _, remote := range serverDetail.Remotes {
|
||||
// Use filter to find servers with this remote URL
|
||||
|
|
@ -246,8 +246,8 @@ func (s *registryServiceImpl) validateNoDuplicateRemoteURLs(ctx context.Context,
|
|||
|
||||
// Check if any conflicting server has a different name
|
||||
for _, conflictingServer := range conflictingServers {
|
||||
if conflictingServer.ServerJSON.Name != serverDetail.Name {
|
||||
return fmt.Errorf("remote URL %s is already used by server %s", remote.URL, conflictingServer.ServerJSON.Name)
|
||||
if conflictingServer.Server.Name != serverDetail.Name {
|
||||
return fmt.Errorf("remote URL %s is already used by server %s", remote.URL, conflictingServer.Server.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -256,17 +256,17 @@ func (s *registryServiceImpl) validateNoDuplicateRemoteURLs(ctx context.Context,
|
|||
}
|
||||
|
||||
// EditServer updates an existing server with new details (admin operation)
|
||||
func (s *registryServiceImpl) EditServer(id string, req model.PublishRequest) (*model.ServerResponse, error) {
|
||||
func (s *registryServiceImpl) EditServer(id string, req apiv1.PublishRequest) (*apiv1.ServerRecord, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Validate the request
|
||||
if err := model.ValidatePublisherExtensions(req); err != nil {
|
||||
if err := validators.ValidatePublisherExtensions(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Validate server name exists and format
|
||||
if _, err := model.ParseServerName(req.Server); err != nil {
|
||||
if _, err := validators.ParseServerName(req.Server); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -278,7 +278,7 @@ func (s *registryServiceImpl) EditServer(id string, req model.PublishRequest) (*
|
|||
}
|
||||
|
||||
// Validate reverse-DNS namespace matching for remote URLs
|
||||
if err := model.ValidateRemoteNamespaceMatch(req.Server); err != nil {
|
||||
if err := validators.ValidateRemoteNamespaceMatch(req.Server); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -288,7 +288,7 @@ func (s *registryServiceImpl) EditServer(id string, req model.PublishRequest) (*
|
|||
}
|
||||
|
||||
// Extract publisher extensions from request
|
||||
publisherExtensions := model.ExtractPublisherExtensions(req)
|
||||
publisherExtensions := validators.ExtractPublisherExtensions(req)
|
||||
|
||||
// Update server in database
|
||||
serverRecord, err := s.db.UpdateServer(ctx, id, req.Server, publisherExtensions)
|
||||
|
|
@ -296,7 +296,6 @@ func (s *registryServiceImpl) EditServer(id string, req model.PublishRequest) (*
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Convert ServerRecord to ServerResponse format
|
||||
response := serverRecord.ToServerResponse()
|
||||
return &response, nil
|
||||
// Return ServerRecord directly (it's now the same as ServerResponse)
|
||||
return serverRecord, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,13 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/modelcontextprotocol/registry/internal/database"
|
||||
"github.com/modelcontextprotocol/registry/internal/model"
|
||||
"github.com/modelcontextprotocol/registry/pkg/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestValidateNoDuplicateRemoteURLs(t *testing.T) {
|
||||
// Create test data
|
||||
existingServers := map[string]*model.ServerDetail{
|
||||
existingServers := map[string]*model.ServerJSON{
|
||||
"existing1": {
|
||||
Name: "com.example/existing-server",
|
||||
Description: "An existing server",
|
||||
|
|
@ -41,13 +41,13 @@ func TestValidateNoDuplicateRemoteURLs(t *testing.T) {
|
|||
|
||||
tests := []struct {
|
||||
name string
|
||||
serverDetail model.ServerDetail
|
||||
serverDetail model.ServerJSON
|
||||
expectError bool
|
||||
errorMsg string
|
||||
}{
|
||||
{
|
||||
name: "no remote URLs - should pass",
|
||||
serverDetail: model.ServerDetail{
|
||||
serverDetail: model.ServerJSON{
|
||||
Name: "com.example/new-server",
|
||||
Description: "A new server with no remotes",
|
||||
VersionDetail: model.VersionDetail{
|
||||
|
|
@ -59,7 +59,7 @@ func TestValidateNoDuplicateRemoteURLs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "new unique remote URLs - should pass",
|
||||
serverDetail: model.ServerDetail{
|
||||
serverDetail: model.ServerJSON{
|
||||
Name: "com.example/new-server",
|
||||
Description: "A new server",
|
||||
VersionDetail: model.VersionDetail{
|
||||
|
|
@ -74,7 +74,7 @@ func TestValidateNoDuplicateRemoteURLs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "duplicate remote URL - should fail",
|
||||
serverDetail: model.ServerDetail{
|
||||
serverDetail: model.ServerJSON{
|
||||
Name: "com.example/new-server",
|
||||
Description: "A new server with duplicate URL",
|
||||
VersionDetail: model.VersionDetail{
|
||||
|
|
@ -89,7 +89,7 @@ func TestValidateNoDuplicateRemoteURLs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "updating same server with same URLs - should pass",
|
||||
serverDetail: model.ServerDetail{
|
||||
serverDetail: model.ServerJSON{
|
||||
Name: "com.example/existing-server", // Same name as existing
|
||||
Description: "Updated existing server",
|
||||
VersionDetail: model.VersionDetail{
|
||||
|
|
@ -107,9 +107,9 @@ func TestValidateNoDuplicateRemoteURLs(t *testing.T) {
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
impl := service.(*registryServiceImpl)
|
||||
|
||||
|
||||
err := impl.validateNoDuplicateRemoteURLs(ctx, tt.serverDetail)
|
||||
|
||||
|
||||
if tt.expectError {
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), tt.errorMsg)
|
||||
|
|
@ -118,4 +118,4 @@ func TestValidateNoDuplicateRemoteURLs(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
package service
|
||||
|
||||
import "github.com/modelcontextprotocol/registry/internal/model"
|
||||
import apiv1 "github.com/modelcontextprotocol/registry/pkg/api/v1"
|
||||
|
||||
// RegistryService defines the interface for registry operations with extension wrapper architecture
|
||||
// RegistryService defines the interface for registry operations
|
||||
type RegistryService interface {
|
||||
// List retrieves servers with extension wrapper format
|
||||
List(cursor string, limit int) ([]model.ServerResponse, string, error)
|
||||
// GetByID retrieves a single server by registry metadata ID with extension wrapper format
|
||||
GetByID(id string) (*model.ServerResponse, error)
|
||||
// List retrieves servers with unified format
|
||||
List(cursor string, limit int) ([]apiv1.ServerRecord, string, error)
|
||||
// GetByID retrieves a single server by registry metadata ID with unified format
|
||||
GetByID(id string) (*apiv1.ServerRecord, error)
|
||||
// Publish publishes a server with separated extensions
|
||||
Publish(req model.PublishRequest) (*model.ServerResponse, error)
|
||||
Publish(req apiv1.PublishRequest) (*apiv1.ServerRecord, error)
|
||||
// EditServer updates an existing server with new details
|
||||
EditServer(id string, req model.PublishRequest) (*model.ServerResponse, error)
|
||||
EditServer(id string, req apiv1.PublishRequest) (*apiv1.ServerRecord, error)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue