-
Notifications
You must be signed in to change notification settings - Fork 7
Sample: api-degradation-scenarios - Simulate partial API failures #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
waldekmastykarz
merged 7 commits into
main
from
copilot/simulate-api-degradation-scenarios
Jan 18, 2026
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
df9ee32
Add api-degradation-scenarios sample with Dev Proxy configurations
Copilot 06546b7
Add web app monitoring dashboard, update dates, author, and follow De…
Copilot 01a9842
Update dates to 2026-01-10 per copilot-instructions.md
Copilot dc89695
Update screenshot to reflect current monitoring dashboard
Copilot cf1c50a
Move config files to .devproxy folder and remove default property values
Copilot 763ffe1
Address review feedback: fix PRESET flag, simplify devproxy commands,…
Copilot 2d3e51f
Updates
waldekmastykarz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
56 changes: 56 additions & 0 deletions
56
samples/api-degradation-scenarios/.devproxy/devproxyrc.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/rc.schema.json", | ||
| "plugins": [ | ||
| { | ||
| "name": "RetryAfterPlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll" | ||
| }, | ||
| { | ||
| "name": "LatencyPlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", | ||
| "configSection": "latencyPlugin" | ||
| }, | ||
| { | ||
| "name": "RateLimitingPlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", | ||
| "configSection": "rateLimitingPlugin" | ||
| }, | ||
| { | ||
| "name": "GenericRandomErrorPlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", | ||
| "configSection": "genericRandomErrorPlugin" | ||
| }, | ||
| { | ||
| "name": "MockResponsePlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", | ||
| "configSection": "mockResponsePlugin" | ||
| } | ||
| ], | ||
| "urlsToWatch": [ | ||
| "https://api.example.com/*" | ||
| ], | ||
| "latencyPlugin": { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/latencyplugin.schema.json", | ||
| "minMs": 3000, | ||
| "maxMs": 5000 | ||
| }, | ||
| "rateLimitingPlugin": { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/ratelimitingplugin.schema.json", | ||
| "costPerRequest": 1, | ||
| "rateLimit": 10 | ||
| }, | ||
| "genericRandomErrorPlugin": { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/genericrandomerrorplugin.schema.json", | ||
| "errorsFile": "errors-503.json", | ||
| "rate": 30 | ||
| }, | ||
| "mockResponsePlugin": { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.schema.json", | ||
| "mocksFile": "mocks.json" | ||
| } | ||
| } |
81 changes: 81 additions & 0 deletions
81
samples/api-degradation-scenarios/.devproxy/errors-503.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/genericrandomerrorplugin.errorsfile.schema.json", | ||
| "errors": [ | ||
| { | ||
| "request": { | ||
| "url": "https://api.example.com/*" | ||
| }, | ||
| "responses": [ | ||
| { | ||
| "statusCode": 503, | ||
| "headers": [ | ||
| { | ||
| "name": "Content-Type", | ||
| "value": "application/json" | ||
| }, | ||
| { | ||
| "name": "Retry-After", | ||
| "value": "@dynamic" | ||
| }, | ||
| { | ||
| "name": "Access-Control-Allow-Origin", | ||
| "value": "*" | ||
| } | ||
| ], | ||
| "body": { | ||
| "error": { | ||
| "code": "ServiceUnavailable", | ||
| "message": "Service is temporarily unavailable. Please retry later." | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "statusCode": 503, | ||
| "headers": [ | ||
| { | ||
| "name": "Content-Type", | ||
| "value": "application/json" | ||
| }, | ||
| { | ||
| "name": "Retry-After", | ||
| "value": "@dynamic" | ||
| }, | ||
| { | ||
| "name": "Access-Control-Allow-Origin", | ||
| "value": "*" | ||
| } | ||
| ], | ||
| "body": { | ||
| "error": { | ||
| "code": "ServerBusy", | ||
| "message": "The server is currently busy. Please try again in a few moments." | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "statusCode": 503, | ||
| "headers": [ | ||
| { | ||
| "name": "Content-Type", | ||
| "value": "application/json" | ||
| }, | ||
| { | ||
| "name": "Retry-After", | ||
| "value": "@dynamic" | ||
| }, | ||
| { | ||
| "name": "Access-Control-Allow-Origin", | ||
| "value": "*" | ||
| } | ||
| ], | ||
| "body": { | ||
| "error": { | ||
| "code": "CapacityExceeded", | ||
| "message": "Server capacity exceeded. Please wait before retrying." | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } |
34 changes: 34 additions & 0 deletions
34
samples/api-degradation-scenarios/.devproxy/intermittent-errors.devproxyrc.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/rc.schema.json", | ||
| "plugins": [ | ||
| { | ||
| "name": "RetryAfterPlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll" | ||
| }, | ||
| { | ||
| "name": "GenericRandomErrorPlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", | ||
| "configSection": "genericRandomErrorPlugin" | ||
| }, | ||
| { | ||
| "name": "MockResponsePlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", | ||
| "configSection": "mockResponsePlugin" | ||
| } | ||
| ], | ||
| "urlsToWatch": [ | ||
| "https://api.example.com/*" | ||
| ], | ||
| "genericRandomErrorPlugin": { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/genericrandomerrorplugin.schema.json", | ||
| "errorsFile": "errors-503.json", | ||
| "rate": 30 | ||
| }, | ||
| "mockResponsePlugin": { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.schema.json", | ||
| "mocksFile": "mocks.json" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.mocksfile.schema.json", | ||
| "mocks": [ | ||
| { | ||
| "request": { | ||
| "url": "https://api.example.com/*" | ||
| }, | ||
| "response": { | ||
| "statusCode": 200, | ||
| "headers": [ | ||
| { | ||
| "name": "Content-Type", | ||
| "value": "application/json" | ||
| }, | ||
| { | ||
| "name": "Access-Control-Allow-Origin", | ||
| "value": "*" | ||
| } | ||
| ], | ||
| "body": { | ||
| "status": "ok", | ||
| "message": "Request processed successfully" | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } |
34 changes: 34 additions & 0 deletions
34
samples/api-degradation-scenarios/.devproxy/rate-limiting.devproxyrc.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/rc.schema.json", | ||
| "plugins": [ | ||
| { | ||
| "name": "RetryAfterPlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll" | ||
| }, | ||
| { | ||
| "name": "RateLimitingPlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", | ||
| "configSection": "rateLimitingPlugin" | ||
| }, | ||
| { | ||
| "name": "MockResponsePlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", | ||
| "configSection": "mockResponsePlugin" | ||
| } | ||
| ], | ||
| "urlsToWatch": [ | ||
| "https://api.example.com/*" | ||
| ], | ||
| "rateLimitingPlugin": { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/ratelimitingplugin.schema.json", | ||
| "costPerRequest": 1, | ||
| "rateLimit": 10 | ||
| }, | ||
| "mockResponsePlugin": { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.schema.json", | ||
| "mocksFile": "mocks.json" | ||
| } | ||
| } |
29 changes: 29 additions & 0 deletions
29
samples/api-degradation-scenarios/.devproxy/slow-responses.devproxyrc.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/rc.schema.json", | ||
| "plugins": [ | ||
| { | ||
| "name": "LatencyPlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", | ||
| "configSection": "latencyPlugin" | ||
| }, | ||
| { | ||
| "name": "MockResponsePlugin", | ||
| "enabled": true, | ||
| "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", | ||
| "configSection": "mockResponsePlugin" | ||
| } | ||
| ], | ||
| "urlsToWatch": [ | ||
| "https://api.example.com/*" | ||
| ], | ||
| "latencyPlugin": { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/latencyplugin.schema.json", | ||
| "minMs": 3000, | ||
| "maxMs": 5000 | ||
| }, | ||
| "mockResponsePlugin": { | ||
| "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.0.0/mockresponseplugin.schema.json", | ||
| "mocksFile": "mocks.json" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| # Simulate API degradation scenarios | ||
|
|
||
| ## Summary | ||
|
|
||
| This sample demonstrates how to simulate various API degradation scenarios to test how your application handles partial failures, intermittent errors, rate limiting, and slow responses. Use these configurations to build apps that gracefully degrade under stress and verify that your error handling and retry logic works before production. | ||
|
|
||
|  | ||
|
|
||
| ## Compatibility | ||
|
|
||
|  | ||
|
|
||
| ## Contributors | ||
|
|
||
| - [Waldek Mastykarz](https://github.com/waldekmastykarz) | ||
|
|
||
| ## Version history | ||
|
|
||
| Version|Date|Comments | ||
| -------|----|-------- | ||
| 1.0|January 18, 2026|Initial release | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - [Node.js LTS](https://nodejs.org) | ||
|
|
||
| ## Minimal path to awesome | ||
|
|
||
| - Clone this repository (or [download this solution as a .ZIP file](https://pnp.github.io/download-partial/?url=https://github.com/pnp/proxy-samples/tree/main/samples/api-degradation-scenarios) then unzip it) | ||
| - Start the sample app and Dev Proxy by running `npm start` | ||
| - In a web browser, navigate to `http://localhost:3000` and use the dashboard to test API degradation scenarios | ||
|
|
||
| ### Using the monitoring dashboard | ||
|
|
||
| The included web app provides a real-time monitoring dashboard that shows: | ||
|
|
||
| - **Total Requests** - Number of requests made | ||
| - **Success Rate** - Percentage of successful requests | ||
| - **Average Response Time** - Average response time across all requests | ||
| - **Error counts** - Breakdown of 503 and 429 errors | ||
| - **Response Distribution** - Visual bar chart of response types | ||
|
|
||
| Use the dashboard buttons to: | ||
|
|
||
| - **Send Single Request** - Make one API request | ||
| - **Send Burst (10 requests)** - Make 10 concurrent requests to trigger rate limiting | ||
| - **Start Auto Requests** - Continuously send requests every second | ||
| - **Stop** - Stop auto requests | ||
| - **Clear Stats** - Reset all statistics | ||
|
|
||
| ### Using Dev Proxy configurations directly | ||
|
|
||
| You can also run Dev Proxy with specific configurations: | ||
|
|
||
| ### All degradation scenarios combined | ||
|
|
||
| This configuration combines all three degradation scenarios: intermittent 503 errors (30% of requests), rate limiting (10 requests per minute), and slow responses (3-5 seconds latency). | ||
|
|
||
| ```bash | ||
| devproxy | ||
| ``` | ||
|
|
||
| ### Intermittent 503 errors only | ||
|
|
||
| This configuration simulates random 503 Service Unavailable errors for 30% of requests. | ||
|
|
||
| ```bash | ||
| devproxy --config-file .devproxy/intermittent-errors.devproxyrc.json | ||
| ``` | ||
|
|
||
| ### Rate limiting only | ||
|
|
||
| This configuration simulates hitting rate limits with 429 Too Many Requests responses after 10 requests per minute. | ||
|
|
||
| ```bash | ||
| devproxy --config-file .devproxy/rate-limiting.devproxyrc.json | ||
| ``` | ||
|
|
||
| ### Slow responses only | ||
|
|
||
| This configuration adds random latency (3-5 seconds) to all responses. | ||
|
|
||
| ```bash | ||
| devproxy --config-file .devproxy/slow-responses.devproxyrc.json | ||
| ``` | ||
|
|
||
| ## Features | ||
|
|
||
| This sample demonstrates how to use Dev Proxy to simulate API degradation scenarios. Using this sample you can: | ||
|
|
||
| - Test your application's handling of intermittent 503 Service Unavailable errors | ||
| - Verify retry logic and exponential backoff implementation | ||
| - Test rate limit handling and proper use of Retry-After headers | ||
| - Measure application performance under slow network conditions | ||
| - Validate graceful degradation patterns in your application | ||
| - Demonstrate that your error handling works before deploying to production | ||
|
|
||
| ### Configuration files | ||
|
|
||
| | File | Description | | ||
| |------|-------------| | ||
| | `.devproxy/devproxyrc.json` | Combined configuration with all degradation scenarios | | ||
| | `.devproxy/intermittent-errors.devproxyrc.json` | 503 errors at 30% failure rate | | ||
| | `.devproxy/rate-limiting.devproxyrc.json` | Rate limiting at 10 requests/minute | | ||
| | `.devproxy/slow-responses.devproxyrc.json` | Random latency between 3-5 seconds | | ||
| | `.devproxy/errors-503.json` | Error responses for the GenericRandomErrorPlugin | | ||
| | `.devproxy/mocks.json` | Mock responses for successful requests | | ||
| | `index.html` | Monitoring dashboard web app | | ||
| | `package.json` | Node.js configuration to run the sample | | ||
|
|
||
| ### Plugins used | ||
|
|
||
| - **GenericRandomErrorPlugin** - Simulates random errors at a configurable rate | ||
| - **LatencyPlugin** - Adds random delays to responses | ||
| - **RateLimitingPlugin** - Simulates API rate limiting behavior | ||
| - **RetryAfterPlugin** - Validates that clients respect Retry-After headers | ||
|
|
||
| ## Help | ||
|
|
||
| We do not support samples, but this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues. | ||
|
|
||
| You can try looking at [issues related to this sample](https://github.com/pnp/proxy-samples/issues?q=label%3A%22sample%3A%20api-degradation-scenarios%22) to see if anybody else is having the same issues. | ||
|
|
||
| If you encounter any issues using this sample, [create a new issue](https://github.com/pnp/proxy-samples/issues/new). | ||
|
|
||
| Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/proxy-samples/issues/new). | ||
|
|
||
| ## Disclaimer | ||
|
|
||
| **THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.** | ||
|
|
||
|  |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.