refactor: consolidate server list response types (#387)
## Summary - Consolidate ServerListResponse and Metadata types into pkg/api/v0 - Remove duplication between handler and API types - Change metadata from optional pointer to required value - Remove unused Total field from Metadata
This commit is contained in:
parent
d43d0bfeef
commit
0eada9b3b4
3 changed files with 19 additions and 47 deletions
|
|
@ -12,13 +12,6 @@ import (
|
|||
apiv0 "github.com/modelcontextprotocol/registry/pkg/api/v0"
|
||||
)
|
||||
|
||||
// Metadata contains pagination metadata
|
||||
type Metadata struct {
|
||||
NextCursor string `json:"next_cursor,omitempty"`
|
||||
Count int `json:"count,omitempty"`
|
||||
Total int `json:"total,omitempty"`
|
||||
}
|
||||
|
||||
// ListServersInput represents the input for listing servers
|
||||
type ListServersInput struct {
|
||||
Cursor string `query:"cursor" doc:"Pagination cursor (UUID)" format:"uuid" required:"false" example:"550e8400-e29b-41d4-a716-446655440000"`
|
||||
|
|
@ -28,12 +21,6 @@ type ListServersInput struct {
|
|||
Version string `query:"version" doc:"Filter by version ('latest' for latest version, or an exact version like '1.2.3')" required:"false" example:"latest"`
|
||||
}
|
||||
|
||||
// ListServersBody represents the paginated server list response body
|
||||
type ListServersBody struct {
|
||||
Servers []apiv0.ServerJSON `json:"servers" doc:"List of MCP servers with extensions"`
|
||||
Metadata *Metadata `json:"metadata,omitempty" doc:"Pagination metadata"`
|
||||
}
|
||||
|
||||
// ServerDetailInput represents the input for getting server details
|
||||
type ServerDetailInput struct {
|
||||
ID string `path:"id" doc:"Server ID (UUID)" format:"uuid"`
|
||||
|
|
@ -49,7 +36,7 @@ func RegisterServersEndpoints(api huma.API, registry service.RegistryService) {
|
|||
Summary: "List MCP servers",
|
||||
Description: "Get a paginated list of MCP servers from the registry",
|
||||
Tags: []string{"servers"},
|
||||
}, func(_ context.Context, input *ListServersInput) (*Response[ListServersBody], error) {
|
||||
}, func(_ context.Context, input *ListServersInput) (*Response[apiv0.ServerListResponse], error) {
|
||||
// Validate cursor if provided
|
||||
if input.Cursor != "" {
|
||||
_, err := uuid.Parse(input.Cursor)
|
||||
|
|
@ -94,21 +81,14 @@ func RegisterServersEndpoints(api huma.API, registry service.RegistryService) {
|
|||
return nil, huma.Error500InternalServerError("Failed to get registry list", err)
|
||||
}
|
||||
|
||||
// Build response body
|
||||
body := ListServersBody{
|
||||
Servers: servers,
|
||||
}
|
||||
|
||||
// Add metadata if there's a next cursor
|
||||
if nextCursor != "" {
|
||||
body.Metadata = &Metadata{
|
||||
NextCursor: nextCursor,
|
||||
Count: len(servers),
|
||||
}
|
||||
}
|
||||
|
||||
return &Response[ListServersBody]{
|
||||
Body: body,
|
||||
return &Response[apiv0.ServerListResponse]{
|
||||
Body: apiv0.ServerListResponse{
|
||||
Servers: servers,
|
||||
Metadata: apiv0.Metadata{
|
||||
NextCursor: nextCursor,
|
||||
Count: len(servers),
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ func TestServersListEndpoint(t *testing.T) {
|
|||
setupRegistryService func(service.RegistryService)
|
||||
expectedStatus int
|
||||
expectedServers []apiv0.ServerJSON
|
||||
expectedMeta *v0.Metadata
|
||||
expectedMeta *apiv0.Metadata
|
||||
expectedError string
|
||||
}{
|
||||
{
|
||||
|
|
@ -268,10 +268,7 @@ func TestServersListEndpoint(t *testing.T) {
|
|||
assert.Equal(t, "application/json", w.Header().Get("Content-Type"))
|
||||
|
||||
// Parse response body
|
||||
var resp struct {
|
||||
Servers []apiv0.ServerJSON `json:"servers"`
|
||||
Metadata *v0.Metadata `json:"metadata,omitempty"`
|
||||
}
|
||||
var resp apiv0.ServerListResponse
|
||||
err := json.NewDecoder(w.Body).Decode(&resp)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
|
@ -297,7 +294,7 @@ func TestServersListEndpoint(t *testing.T) {
|
|||
default:
|
||||
assert.NotEmpty(t, resp.Servers, "Expected at least one server")
|
||||
}
|
||||
|
||||
|
||||
// General structure validation
|
||||
for _, server := range resp.Servers {
|
||||
assert.NotEmpty(t, server.Name)
|
||||
|
|
@ -311,11 +308,9 @@ func TestServersListEndpoint(t *testing.T) {
|
|||
// Check metadata if expected
|
||||
if tc.expectedMeta != nil {
|
||||
assert.NotNil(t, resp.Metadata, "Expected metadata to be present")
|
||||
if resp.Metadata != nil {
|
||||
assert.Equal(t, tc.expectedMeta.Count, resp.Metadata.Count)
|
||||
if tc.expectedMeta.NextCursor != "" {
|
||||
assert.NotEmpty(t, resp.Metadata.NextCursor)
|
||||
}
|
||||
assert.Equal(t, tc.expectedMeta.Count, resp.Metadata.Count)
|
||||
if tc.expectedMeta.NextCursor != "" {
|
||||
assert.NotEmpty(t, resp.Metadata.NextCursor)
|
||||
}
|
||||
}
|
||||
} else if tc.expectedError != "" {
|
||||
|
|
@ -336,7 +331,7 @@ func TestServersDetailEndpoint(t *testing.T) {
|
|||
testServer, err := registryService.Publish(apiv0.ServerJSON{
|
||||
Name: "com.example/test-server",
|
||||
Description: "A test server",
|
||||
Version: "1.0.0",
|
||||
Version: "1.0.0",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
|
@ -466,9 +461,7 @@ func TestServersEndpointsIntegration(t *testing.T) {
|
|||
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
|
||||
|
||||
// Parse response body
|
||||
var listResp struct {
|
||||
Servers []apiv0.ServerJSON `json:"servers"`
|
||||
}
|
||||
var listResp apiv0.ServerListResponse
|
||||
err = json.NewDecoder(resp.Body).Decode(&listResp)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ type RegistryExtensions struct {
|
|||
// ServerListResponse represents the paginated server list response
|
||||
type ServerListResponse struct {
|
||||
Servers []ServerJSON `json:"servers"`
|
||||
Metadata *Metadata `json:"metadata,omitempty"`
|
||||
Metadata Metadata `json:"metadata"`
|
||||
}
|
||||
|
||||
// ServerMeta represents the structured metadata with known extension fields
|
||||
|
|
@ -42,6 +42,5 @@ type ServerJSON struct {
|
|||
// Metadata represents pagination metadata
|
||||
type Metadata struct {
|
||||
NextCursor string `json:"next_cursor,omitempty"`
|
||||
Count int `json:"count,omitempty"`
|
||||
Total int `json:"total,omitempty"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue