소스 정보
- 저장소
- tools-only/X-Skills
- 최근 소스 활동
- 2026년 2월 9일 04:08
- 감지된 SKILL.md 언어
- 영어
- 스타
- 7
- 포크
- 1
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/tools-only/X-Skills --skill migrate-api명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
SOC 직업 분류 기준
| name | migrate-api |
| description | Migrate API to new version with compatibility layers and automated scripts |
| shortcut | mig |
Orchestrate comprehensive API version migrations with automated compatibility layers, breaking change detection, and zero-downtime deployment strategies. This command manages the complete lifecycle of API evolution from initial analysis through deployment and deprecation.
Architecture Approach:
Alternatives Considered:
USE when:
DON'T USE when:
Required:
Recommended:
Step 1: Analysis and Impact Assessment
Step 2: Compatibility Layer Generation
Step 3: Migration Script Creation
Step 4: Routing and Deployment Configuration
Step 5: Validation and Monitoring
migration_plan:
api_name: "User Service API"
source_version: "v1"
target_version: "v2"
breaking_changes:
- endpoint: "/users"
change_type: "field_removed"
field: "username"
severity: "high"
affected_consumers: 15
- endpoint: "/users/{id}"
change_type: "response_structure"
details: "Nested address object"
severity: "medium"
affected_consumers: 8
compatibility_layer:
adapters_generated: 12
transformation_functions: 8
fallback_strategies: 5
migration_scripts:
- script: "001_add_email_unique_constraint.sql"
type: "database"
rollback: "001_rollback_email_constraint.sql"
- script: "002_backfill_address_objects.js"
type: "data_transformation"
estimated_time: "15 minutes"
// API v1 → v2 Migration: User endpoint restructure
// BREAKING: Flattened user object to nested structure
// Source: /api/v1/users/{id}
{
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"zip": "94105"
}
// Target: /api/v2/users/{id}
{
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"address": {
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"postalCode": "94105"
},
"metadata": {
"createdAt": "2024-01-15T10:30:00Z",
"version": "v2"
}
}
// Generated Compatibility Adapter
class UserV1ToV2Adapter {
transform(v1Response) {
return {
id: v1Response.id,
name: v1Response.name,
email: v1Response.email,
: {
: v1Response.,
: v1Response.,
: v1Response.,
: v1Response.
},
: {
: v1Response. || ().(),
:
}
};
}
() {
{
: v2Response.,
: v2Response.,
: v2Response.,
: v2Response.?. || ,
: v2Response.?. || ,
: v2Response.?. || ,
: v2Response.?. ||
};
}
}
routingRules = {
: {
: ,
: ,
: {
: ,
: ,
:
}
}
};
;
-- address table normalized structure
(
id ,
user_id (id),
street (),
city (),
state (),
postal_code (),
created_at ()
);
-- existing flat data to nested structure
(user_id, street, city, state, postal_code)
id, street, city, state, zip
users
street ;
-- foreign key to users table
users address_id (id);
users u
address_id = ua.
user_addresses ua
u. = ua.;
-- old (don
# Schema v1 (Deprecated)
type User {
id: ID!
username: String! # DEPRECATED: Replaced by email
email: String
fullName: String
}
type Query {
user(id: ID!): User
users: [User!]!
}
# Schema v2 (Current)
type Address {
street: String!
city: String!
state: String!
postalCode: String!
country: String!
}
type User {
id: ID!
email: String
String
UserProfile
Address
UserProfile
String
String
String
String
user ID, String User
users UserFilter User
UserFilter
String
String
String
User
ID
String
UserProfile
Address
const resolvers
async _, args, context >
const version context.apiVersion;
if version 'v1'
// Legacy lookup by username
const user await db.users.findByUsernameargs.id;
return
user,
user.username, // Still supported in v1
`{user.firstName {user.lastName`
;
else
// Modern lookup by email or ID
const user await db.users.findOne
args.email ? args.email args.id
;
return user;
,
// Compatibility field resolver for deprecated username
user, args, context >
if context.apiVersion 'v1'
return user.username;
// Add deprecation warning to response headers
context.res.set'Deprecation', 'username field is deprecated. Use email.';
return user.username user.email.split'@';
,
// Transform flat structure to nested for v2+
user >
user.firstName user.fullName?.split' ',
user.lastName user.fullName?.split' ',
user.fullName,
user.avatar
;
// Automated Compatibility Tests
describe'GraphQL Migration Tests', >
test'v1 clients can still with username', async >
const ` user username email `;
const result await executeQuery, 'v1' ;
expectresult.data.user.username.toBe'johndoe';
;
test'v2 clients receive nested profile structure', async >
const ` user profile firstName lastName `;
const result await executeQuery, 'v2' ;
expectresult.data.user.profile.firstName.toBe'John';
;
test'deprecated fields trigger warning headers', async >
const ` user username `;
const response await executeQueryWithHeaders, 'v2' ;
expectresponse.headers.get'Deprecation'.toContain'username field is deprecated';
;
;
// service_v1.proto (Deprecated)
syntax = "proto3";
package user.v1;
message User {
int32 id = 1;
string username = 2;
string email = 3;
string full_name = 4;
}
message GetUserRequest {
int32 id = 1;
}
message GetUserResponse {
User user = 1;
}
service UserService {
rpc GetUser(GetUserRequest) returns (GetUserResponse);
}
// service_v2.proto (Current)
syntax = "proto3";
package user.v2;
import "google/protobuf/timestamp.proto";
message Address {
string street = 1;
string city = 2;
string state = 3;
string postal_code = 4;
string country = 5;
}
message UserProfile {
string first_name = 1;
string last_name = 2;
string display_name = 3;
string avatar_url = 4;
}
message User {
int32 id = 1;
string email = 2;
UserProfile profile = 3;
Address address = 4;
google.protobuf.Timestamp created_at = 5;
google.protobuf.Timestamp updated_at = 6;
}
message GetUserRequest {
oneof identifier {
int32 id = 1;
string email = 2;
}
}
message GetUserResponse {
User user = 1;
}
service UserService {
rpc GetUser(GetUserRequest) returns (GetUserResponse);
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
}
// Compatibility Bridge Service
package user.bridge;
import "user/v1/service.proto";
import "user/v2/service.proto";
class UserServiceBridge {
constructor() {
this.v2Service = new user.v2.UserServiceClient('localhost:50052');
}
// Implement v1 interface while calling v2 backend
async GetUser(call, callback) {
const v1Request = call.request;
// Transform v1 request to v2 format
const v2Request = {
id: v1Request.id
};
try {
const v2Response = await this.v2Service.GetUser(v2Request);
const v2User = v2Response.user;
// Transform v2 response back to v1 format
const v1User = {
id: v2User.id,
username: v2User.email.split('@')[0], // Synthesize username
email: v2User.email,
full_name: v2User.profile.display_name
};
callback(null, { user: v1User });
// Log deprecation warning
console.warn(`[DEPRECATED] v1 API used by client ${call.getPeer()}`);
} catch (error) {
callback(error);
}
}
}
// Envoy gRPC Gateway Configuration for Version Routing
static_resources:
listeners:
- name: user_service_listener
address:
socket_address:
address: 0.0.0.0
port_value: 50051
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: grpc_json
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: user_service
domains: ["*"]
routes:
# Route v1 requests to compatibility bridge
- match:
prefix: "/user.v1.UserService"
route:
cluster: user_service_v1_bridge
timeout: 30s
# Route v2 requests to native service
- match:
prefix: "/user.v2.UserService"
route:
cluster: user_service_v2
timeout: 30s
clusters:
- name: user_service_v1_bridge
connect_timeout: 1s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
http2_protocol_options: {}
load_assignment:
cluster_name: user_service_v1_bridge
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: user-bridge-service
port_value: 50051
- name: user_service_v2
connect_timeout: 1s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
http2_protocol_options: {}
load_assignment:
cluster_name: user_service_v2
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: user-service-v2
port_value: 50052
// Migration Testing Framework
describe('gRPC API Migration Tests', () => {
const v1Client = new user.v1.UserServiceClient('localhost:50051');
const v2Client = new user.v2.UserServiceClient('localhost:50052');
test('v1 clients receive compatible responses', async () => {
const request = new user.v1.GetUserRequest({ id: 123 });
const response = await v1Client.GetUser(request);
expect(response.user.username).toBeDefined();
expect(response.user.email).toBeDefined();
expect(response.user.full_name).toBeDefined();
});
test('v2 clients receive enhanced data structures', async () => {
const request = new user.v2.GetUserRequest({ email: 'john@example.com' });
const response = await v2Client.GetUser(request);
expect(response.user.profile).toBeDefined();
expect(response.user.profile.first_name).toBeDefined();
expect(response.user.address).toBeDefined();
});
test('data consistency between versions', async () => {
const userId = 123;
const v1Response = await v1Client.GetUser({ id: userId });
const v2Response = await v2Client.GetUser({ id: userId });
// Verify transformed data matches
expect(v1Response.user.email).toBe(v2Response.user.email);
expect(v1Response.user.full_name).toBe(v2Response.user.profile.display_name);
});
});
Basic Usage:
/migrate-api \
--source=v1 \
--target=v2 \
--api-spec=openapi.yaml \
--consumers=consumer-registry.json
Available Options:
--strategy <type> - Migration deployment strategy
canary - Gradual traffic shifting (default, safest)blue-green - Instant switchover with rollback capabilityrolling - Progressive deployment across instancesfeature-flag - Application-controlled version selectionparallel-run - Run both versions, compare results--compatibility-mode <mode> - Backward compatibility approach
adapter - Transform requests/responses between versions (default)proxy - Route old endpoints to new implementationshim - Minimal compatibility layer, consumers must adaptnone - No compatibility, hard cutover (dangerous)--deprecation-period <duration> - Support window for old version
3months - Short deprecation (minor changes)6months - Standard deprecation (default)12months - Extended support (major changes)custom:YYYY-MM-DD - Specific sunset date--breaking-changes-policy <policy> - How to handle breaking changes
require-adapters - Force compatibility layer generationwarn-consumers - Send notifications, allow migration timeblock-deployment - Prevent deploy until consumers updateddocument-only - Just update documentation--traffic-split <percentage> - Initial new version traffic
0 (dark launch)10 for 10% canary deployment--rollback-threshold <percentage> - Error rate trigger for auto-rollback
5 (5% error rate)2 for strict quality requirements--test-coverage-required <percentage> - Minimum test coverage before deploy
80--generate-migration-guide - Create consumer migration documentation
--dry-run - Simulate migration without making changes
Common Errors and Solutions:
Error: Breaking changes detected without compatibility layer
ERROR: 15 breaking changes detected in target API version
- Removed field: User.username (affects 12 endpoints)
- Changed type: Order.total (string → number)
- Renamed endpoint: /users/search → /users/find
Solution: Either:
1. Add --compatibility-mode=adapter to generate transformers
2. Create manual adapters in adapters/ directory
3. Use --breaking-changes-policy=warn-consumers for grace period
Error: Consumer test failures in compatibility mode
ERROR: 3 consumer integration tests failed with v2 adapter
- AcmeApp: Expected username field, received null
- BetaCorp: Response schema validation failed
- GammaInc: Authentication token format mismatch
Solution:
1. Review consumer test failures: npm run test:consumers
2. Update adapters to handle edge cases
3. Contact affected consumers for migration coordination
4. Use --traffic-split=0 for dark launch until resolved
Error: Database migration rollback required
ERROR: Migration script 003_add_foreign_keys.sql failed
Constraint violation: user_addresses.user_id references missing users
Solution:
1. Execute rollback: psql -f 003_rollback.sql
2. Fix data inconsistencies: npm run data:cleanup
3. Re-run migration with --validate-data flag
4. Check migration logs: tail -f logs/migration.log
Error: Traffic spike indicating rollback needed
WARNING: v1 traffic increased from 10% to 45% in 5 minutes
Possible rollback from consumers due to v2 issues
Solution:
1. Check v2 error rates: /metrics/api/v2/errors
2. Review recent v2 deployment logs
3. Pause traffic shift: kubectl patch deployment api-gateway --type=json -p='[{"op":"replace","path":"/spec/template/spec/containers/0/env/1/value","value":"10"}]'
4. Investigate root cause before continuing rollout
Error: Incompatible schema versions in distributed system
ERROR: Service A running v2 schema, Service B still on v1
Message deserialization failed: unknown field 'profile'
Solution:
1. Implement schema registry: npm install @kafkajs/schema-registry
2. Use forward-compatible schemas with optional fields
3. Deploy with version negotiation: --enable-version-negotiation
4. Coordinate deployment order across services
DO:
DON'T:
TIPS:
/api-contract-generator - Generate OpenAPI specs from code/api-versioning-manager - Manage multiple API versions/api-documentation-generator - Update docs for new versions/api-monitoring-dashboard - Track version adoption metrics/api-security-scanner - Audit security across versions/api-load-tester - Performance test both versions/api-sdk-generator - Create client libraries for v2Migration Performance Impact:
Optimization Strategies:
Capacity Planning:
Version Transition Security:
Security Checklist:
Issue: Consumers report intermittent failures after migration
Issue: Adapter performance degrading over time
Issue: Version metrics not appearing in dashboard
Issue: Rollback triggered unexpectedly
v1.0.0 (2024-01-15)
v1.1.0 (2024-02-10)
v1.2.0 (2024-03-05)
v1.3.0 (2024-04-20)
v2.0.0 (2024-06-15)
v2.1.0 (2024-08-30) - Current