{"id":30754171,"url":"https://github.com/fkucukkara/apiversioningplayground","last_synced_at":"2025-09-04T09:08:04.861Z","repository":{"id":311299288,"uuid":"1043178152","full_name":"fkucukkara/apiVersioningPlayground","owner":"fkucukkara","description":"A comprehensive demonstration of API versioning strategies in ASP.NET Core using both Controller-based and Minimal API approaches.","archived":false,"fork":false,"pushed_at":"2025-08-23T09:56:57.000Z","size":12,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-24T03:57:34.514Z","etag":null,"topics":["api-versioning","controllers","copilot","custom-instuctions","dotnet-core","minimal-api"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fkucukkara.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-23T09:53:35.000Z","updated_at":"2025-08-23T09:57:40.000Z","dependencies_parsed_at":"2025-08-24T04:59:53.921Z","dependency_job_id":"c4e53949-dce2-4775-aee9-e87f4b5cf1f9","html_url":"https://github.com/fkucukkara/apiVersioningPlayground","commit_stats":null,"previous_names":["fkucukkara/apiversioningplayground"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/fkucukkara/apiVersioningPlayground","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fkucukkara%2FapiVersioningPlayground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fkucukkara%2FapiVersioningPlayground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fkucukkara%2FapiVersioningPlayground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fkucukkara%2FapiVersioningPlayground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fkucukkara","download_url":"https://codeload.github.com/fkucukkara/apiVersioningPlayground/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fkucukkara%2FapiVersioningPlayground/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273581224,"owners_count":25131393,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-04T02:00:08.968Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-versioning","controllers","copilot","custom-instuctions","dotnet-core","minimal-api"],"created_at":"2025-09-04T09:06:44.646Z","updated_at":"2025-09-04T09:08:04.851Z","avatar_url":"https://github.com/fkucukkara.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# API Versioning Playground\n\nA comprehensive demonstration of API versioning strategies in ASP.NET Core using both **Controller-based** and **Minimal API** approaches. This project showcases best practices for implementing API versioning using the `Asp.Versioning` library.\n\n## 📋 Table of Contents\n\n- [Overview](#overview)\n- [Project Structure](#project-structure)\n- [API Versioning Strategies](#api-versioning-strategies)\n- [Implementation Approaches](#implementation-approaches)\n  - [Controller-Based API](#controller-based-api)\n  - [Minimal API](#minimal-api)\n- [Getting Started](#getting-started)\n- [Testing the APIs](#testing-the-apis)\n- [Key Differences Between Versions](#key-differences-between-versions)\n- [Best Practices](#best-practices)\n- [Additional Resources](#additional-resources)\n\n## 🎯 Overview\n\nAPI versioning is crucial for maintaining backward compatibility while evolving your APIs. This playground demonstrates:\n\n- **URL Segment Versioning**: Using version numbers in the URL path (`/api/v1/products`, `/api/v2/products`)\n- **Multiple API Versions**: Supporting both v1.0 and v2.0 simultaneously\n- **Different Implementation Patterns**: Controller-based vs Minimal API approaches\n- **OpenAPI Integration**: Swagger documentation with version-aware endpoints\n\n## 📁 Project Structure\n\n```\napiVersioningPlayground/\n├── apiVersioningPlayground.sln          # Solution file\n├── global.json                          # .NET SDK version configuration\n├── README.md                           # This documentation\n├── controllerBasedAPI/                 # Traditional controller approach\n│   ├── Controllers/\n│   │   └── ProductController.cs        # Versioned controller endpoints\n│   ├── Program.cs                      # Startup configuration\n│   ├── controllerBasedAPI.csproj      # Project dependencies\n│   └── controllerBasedAPI.http        # HTTP test requests\n└── minimalAPI/                        # Modern minimal API approach\n    ├── Program.cs                      # All configuration and endpoints\n    ├── minimalAPI.csproj              # Project dependencies\n    └── minimalAPI.http                # HTTP test requests\n```\n\n## 🔄 API Versioning Strategies\n\nThis project implements **URL Segment Versioning**, where the version is embedded in the URL path:\n\n```\nGET /api/v1/products    # Version 1.0\nGET /api/v2/products    # Version 2.0\n```\n\n### Why URL Segment Versioning?\n\n- ✅ **Clear and Explicit**: Version is immediately visible in the URL\n- ✅ **Cache-Friendly**: Different URLs can be cached independently\n- ✅ **Easy Testing**: Simple to test different versions with tools like Postman\n- ✅ **Documentation-Friendly**: Clear separation in API documentation\n\n## 🏗️ Implementation Approaches\n\n### Controller-Based API\n\nThe traditional ASP.NET Core approach using controllers and attributes.\n\n#### Configuration (`Program.cs`)\n\n```csharp\n// Add API versioning\nbuilder.Services.AddApiVersioning(options =\u003e\n{\n    options.DefaultApiVersion = new ApiVersion(1, 0);\n    options.AssumeDefaultVersionWhenUnspecified = true;\n    options.ApiVersionReader = ApiVersionReader.Combine(\n        new UrlSegmentApiVersionReader()\n    );\n}).AddMvc();\n```\n\n#### Controller Implementation\n\n```csharp\n[ApiController]\n[Route(\"api/v{version:apiVersion}/[controller]\")]\npublic class ProductController : ControllerBase\n{\n    [HttpGet]\n    [ApiVersion(\"1.0\")]\n    public IActionResult GetProductsV1() { /* ... */ }\n\n    [HttpGet]\n    [ApiVersion(\"2.0\")]\n    public IActionResult GetProductsV2() { /* ... */ }\n}\n```\n\n#### Key Features:\n- Uses `[ApiVersion]` attributes to specify supported versions\n- Route template includes `{version:apiVersion}` placeholder\n- Separate methods for different versions\n- Rich metadata support with `[EndpointSummary]` and `[Tags]`\n\n### Minimal API\n\nThe modern, streamlined approach using endpoint routing.\n\n#### Configuration (`Program.cs`)\n\n```csharp\nbuilder.Services.AddApiVersioning(options =\u003e\n{\n    options.DefaultApiVersion = new ApiVersion(1, 0);\n    options.AssumeDefaultVersionWhenUnspecified = true;\n    options.ApiVersionReader = ApiVersionReader.Combine(\n        new UrlSegmentApiVersionReader()\n    );\n});\n```\n\n#### Endpoint Registration\n\n```csharp\n// Create API version set\nvar versionSet = app.NewApiVersionSet(\"Products API\")\n    .HasApiVersion(new ApiVersion(1, 0))\n    .HasApiVersion(new ApiVersion(2, 0))\n    .Build();\n\n// Version 1 endpoints\nvar v1Group = app.MapGroup(\"/api/v{version:apiVersion}/products\")\n    .WithTags(\"Products v1\");\n\nv1Group.MapGet(\"\", GetProductsV1)\n    .WithApiVersionSet(versionSet)\n    .MapToApiVersion(new ApiVersion(1, 0));\n```\n\n#### Key Features:\n- Uses `NewApiVersionSet()` to define supported versions\n- Endpoint groups with `MapGroup()` for organization\n- Fluent API for configuration with `WithApiVersionSet()`\n- Static methods as endpoint handlers\n\n## 🚀 Getting Started\n\n### Prerequisites\n\n- [.NET 9.0 SDK](https://dotnet.microsoft.com/download/dotnet/9.0)\n- Your favorite IDE (Visual Studio, VS Code, Rider)\n\n### Running the Projects\n\n1. **Clone the repository**\n   ```bash\n   git clone \u003crepository-url\u003e\n   cd apiVersioningPlayground\n   ```\n\n2. **Run the Controller-Based API**\n   ```bash\n   cd controllerBasedAPI\n   dotnet run\n   ```\n   API will be available at: `https://localhost:5163` or `http://localhost:5163`\n\n3. **Run the Minimal API** (in a separate terminal)\n   ```bash\n   cd minimalAPI\n   dotnet run\n   ```\n   API will be available at: `https://localhost:5050` or `http://localhost:5050`\n\n4. **View OpenAPI Documentation**\n   - Controller API: `https://localhost:5163/openapi/v1.json`\n   - Minimal API: `https://localhost:5050/openapi/v1.json`\n\n## 🧪 Testing the APIs\n\nBoth projects include `.http` files for easy testing with VS Code REST Client extension or similar tools.\n\n### Example Requests\n\n#### Version 1 (Simple Format)\n```http\nGET /api/v1/products\n# Response:\n[\n  { \"id\": 1, \"name\": \"Laptop\", \"price\": 999.99 },\n  { \"id\": 2, \"name\": \"Mouse\", \"price\": 29.99 }\n]\n```\n\n#### Version 2 (Enhanced Format)\n```http\nGET /api/v2/products\n# Response:\n{\n  \"data\": [\n    {\n      \"id\": 1,\n      \"name\": \"Laptop\",\n      \"price\": 999.99,\n      \"category\": \"Electronics\",\n      \"inStock\": true,\n      \"createdAt\": \"2024-07-24T10:30:00Z\"\n    }\n  ],\n  \"total\": 1,\n  \"version\": \"2.0\"\n}\n```\n\n### Testing with curl\n\n```bash\n# Version 1\ncurl -X GET \"http://localhost:5163/api/v1/product\" -H \"accept: application/json\"\n\n# Version 2\ncurl -X GET \"http://localhost:5163/api/v2/product\" -H \"accept: application/json\"\n\n# Create product (v2 only)\ncurl -X POST \"http://localhost:5163/api/v2/product\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Gaming Mouse\",\"price\":89.99,\"category\":\"Gaming\"}'\n```\n\n## 🔍 Key Differences Between Versions\n\n| Feature | Version 1.0 | Version 2.0 |\n|---------|-------------|-------------|\n| **Data Format** | Simple objects | Enhanced with metadata |\n| **Product Fields** | `Id`, `Name`, `Price` | + `Category`, `InStock`, `CreatedAt`, `Description`, `Tags` |\n| **Response Structure** | Direct array | Wrapped with metadata (`Data`, `Total`, `Version`) |\n| **Available Operations** | GET only | GET + POST (Create) |\n| **Validation** | Basic | Enhanced with detailed error messages |\n\n### Version Evolution Strategy\n\n- **v1.0**: Minimal viable product with core functionality\n- **v2.0**: Enhanced features, richer data model, additional operations\n- **Future versions**: Can add new fields, operations, or modify business logic\n\n## 📖 Best Practices\n\n### 1. **Consistent Versioning Strategy**\n- Choose one versioning method and stick with it\n- Use semantic versioning (Major.Minor format)\n- Document version differences clearly\n\n### 2. **Backward Compatibility**\n- Keep older versions functional during transition periods\n- Provide migration guides for breaking changes\n- Use deprecation notices before removing versions\n\n### 3. **Default Version Handling**\n```csharp\noptions.DefaultApiVersion = new ApiVersion(1, 0);\noptions.AssumeDefaultVersionWhenUnspecified = true;\n```\n\n### 4. **Clear Documentation**\n- Use `[EndpointSummary]` and `[EndpointDescription]` attributes\n- Group endpoints by version using `[Tags]`\n- Provide examples for each version\n\n### 5. **Testing Strategy**\n- Test all supported versions\n- Validate version-specific behavior\n- Use automated tests for regression prevention\n\n### 6. **Monitoring and Analytics**\n- Track version usage to understand adoption\n- Monitor performance across versions\n- Plan deprecation based on usage data\n\n## 🔧 Configuration Options\n\nThe `Asp.Versioning` library supports multiple versioning strategies:\n\n```csharp\nbuilder.Services.AddApiVersioning(options =\u003e\n{\n    options.DefaultApiVersion = new ApiVersion(1, 0);\n    options.AssumeDefaultVersionWhenUnspecified = true;\n    \n    // Multiple readers can be combined\n    options.ApiVersionReader = ApiVersionReader.Combine(\n        new UrlSegmentApiVersionReader(),           // /api/v1/products\n        new QueryStringApiVersionReader(),          // ?version=1.0\n        new HeaderApiVersionReader(\"X-Version\"),    // X-Version: 1.0\n        new MediaTypeApiVersionReader()             // application/json;v=1.0\n    );\n});\n```\n\n## 📚 Additional Resources\n\n- [ASP.NET Core API Versioning Documentation](https://github.com/dotnet/aspnet-api-versioning)\n- [API Versioning Best Practices](https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design#versioning-a-restful-web-api)\n- [OpenAPI Specification](https://swagger.io/specification/)\n- [REST API Design Guidelines](https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design)\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffkucukkara%2Fapiversioningplayground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffkucukkara%2Fapiversioningplayground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffkucukkara%2Fapiversioningplayground/lists"}