diff --git a/.github/skills/validate-devproxy-sample/SKILL.md b/.github/skills/validate-devproxy-sample/SKILL.md index 7a98644..d283c76 100644 --- a/.github/skills/validate-devproxy-sample/SKILL.md +++ b/.github/skills/validate-devproxy-sample/SKILL.md @@ -215,6 +215,30 @@ Acceptable curl when: - Single request/response - Quick verification +### 10. URL Domain Validation + +**Check**: Do URLs use proxy-friendly domains? + +**Avoid these TLDs** — they're often excluded from system proxy settings: +- `.local` — Reserved for mDNS/Bonjour, typically bypasses proxy +- `.localhost` — Loopback, excluded by most systems +- `.internal` — Often excluded in enterprise environments +- `.test` — Reserved TLD, may have issues + +**Use instead:** +- `.contoso.com` — Microsoft's example domain (safe, won't resolve) +- `.example.com` — IANA reserved for documentation +- `.fabrikam.com` — Another Microsoft example domain +- Real API domains you're mocking + +**Why this matters**: When browsers/apps detect `.local` domains, they often skip the proxy entirely, making Dev Proxy unable to intercept requests. + +**Check in files:** +- `urlsToWatch` in `devproxyrc.json` +- `baseUrl` in CRUD API files +- API URLs in frontend code (JavaScript, HTML) +- Mock response URLs + ## Common Mistakes Summary | Mistake | How to Fix | @@ -230,6 +254,7 @@ Acceptable curl when: | curl without proxy | Add `-ikx http://127.0.0.1:8000` | | Wrong schema type | Match schema to file purpose | | Missing tracking pixel | Add at end of README | +| Using `.local` TLD | Change to `.contoso.com` or similar | ## Validation Script @@ -281,4 +306,5 @@ Before creating a PR: 8. [ ] curl commands include proxy flag 9. [ ] README has tracking pixel 10. [ ] Badge version matches PROXY VERSION -11. [ ] VS Code shows no Problems +11. [ ] URLs don't use `.local` or other excluded TLDs +12. [ ] VS Code shows no Problems diff --git a/samples/full-stack-no-backend/.devproxy/cors-mocks.json b/samples/full-stack-no-backend/.devproxy/cors-mocks.json new file mode 100644 index 0000000..5e6c3db --- /dev/null +++ b/samples/full-stack-no-backend/.devproxy/cors-mocks.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.1.0/mockresponseplugin.mocksfile.schema.json", + "mocks": [ + { + "request": { + "url": "https://api.contoso.com/*", + "method": "OPTIONS" + }, + "response": { + "statusCode": 204, + "headers": [ + { "name": "Access-Control-Allow-Origin", "value": "*" }, + { "name": "Access-Control-Allow-Methods", "value": "GET, POST, PATCH, DELETE, OPTIONS" }, + { "name": "Access-Control-Allow-Headers", "value": "Content-Type, x-api-key" }, + { "name": "Access-Control-Max-Age", "value": "86400" } + ] + } + } + ] +} diff --git a/samples/full-stack-no-backend/.devproxy/devproxyrc.json b/samples/full-stack-no-backend/.devproxy/devproxyrc.json new file mode 100644 index 0000000..15de37a --- /dev/null +++ b/samples/full-stack-no-backend/.devproxy/devproxyrc.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.1.0/rc.schema.json", + "plugins": [ + { + "name": "MockResponsePlugin", + "enabled": true, + "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", + "configSection": "corsPlugin" + }, + { + "name": "LatencyPlugin", + "enabled": true, + "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", + "configSection": "latencyPlugin" + }, + { + "name": "AuthPlugin", + "enabled": true, + "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", + "configSection": "authPlugin" + }, + { + "name": "CrudApiPlugin", + "enabled": true, + "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll", + "configSection": "tasksApi" + }, + { + "name": "DevToolsPlugin", + "enabled": true, + "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll" + } + ], + "urlsToWatch": [ + "https://api.contoso.com/*" + ], + "corsPlugin": { + "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.1.0/mockresponseplugin.schema.json", + "mocksFile": "cors-mocks.json" + }, + "latencyPlugin": { + "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.1.0/latencyplugin.schema.json", + "minMs": 200, + "maxMs": 800 + }, + "authPlugin": { + "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.1.0/authplugin.schema.json", + "type": "apiKey", + "apiKey": { + "parameters": [ + { + "in": "header", + "name": "x-api-key" + } + ], + "allowedKeys": [ + "dev-proxy-demo-key" + ] + } + }, + "tasksApi": { + "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.1.0/crudapiplugin.schema.json", + "apiFile": "tasks-api.json" + } +} diff --git a/samples/full-stack-no-backend/.devproxy/tasks-api.json b/samples/full-stack-no-backend/.devproxy/tasks-api.json new file mode 100644 index 0000000..14df786 --- /dev/null +++ b/samples/full-stack-no-backend/.devproxy/tasks-api.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v2.1.0/crudapiplugin.apifile.schema.json", + "baseUrl": "https://api.contoso.com/tasks", + "dataFile": "tasks-data.json", + "enableCors": true, + "actions": [ + { + "action": "getAll" + }, + { + "action": "getOne", + "url": "/{task-id}", + "query": "$.[?(@.id == {task-id})]" + }, + { + "action": "create" + }, + { + "action": "merge", + "url": "/{task-id}", + "query": "$.[?(@.id == {task-id})]" + }, + { + "action": "delete", + "url": "/{task-id}", + "query": "$.[?(@.id == {task-id})]" + } + ] +} diff --git a/samples/full-stack-no-backend/.devproxy/tasks-data.json b/samples/full-stack-no-backend/.devproxy/tasks-data.json new file mode 100644 index 0000000..9c58b1d --- /dev/null +++ b/samples/full-stack-no-backend/.devproxy/tasks-data.json @@ -0,0 +1,47 @@ +[ + { + "id": 1, + "title": "Set up Dev Proxy", + "description": "Install and configure Dev Proxy for the project", + "status": "completed", + "priority": "high", + "dueDate": "2026-01-05", + "createdAt": "2026-01-01" + }, + { + "id": 2, + "title": "Create task manager UI", + "description": "Build the frontend interface for managing tasks", + "status": "in-progress", + "priority": "high", + "dueDate": "2026-01-10", + "createdAt": "2026-01-02" + }, + { + "id": 3, + "title": "Add authentication", + "description": "Implement API key authentication using AuthPlugin", + "status": "pending", + "priority": "medium", + "dueDate": "2026-01-15", + "createdAt": "2026-01-03" + }, + { + "id": 4, + "title": "Write documentation", + "description": "Document the sample and how to use it", + "status": "pending", + "priority": "low", + "dueDate": "2026-01-20", + "createdAt": "2026-01-04" + }, + { + "id": 5, + "title": "Test offline functionality", + "description": "Verify the app works completely offline with Dev Proxy", + "status": "pending", + "priority": "medium", + "dueDate": "2026-01-18", + "createdAt": "2026-01-05" + } +] diff --git a/samples/full-stack-no-backend/README.md b/samples/full-stack-no-backend/README.md new file mode 100644 index 0000000..7123006 --- /dev/null +++ b/samples/full-stack-no-backend/README.md @@ -0,0 +1,123 @@ +# Build complete app with zero backend + +## Summary + +This sample demonstrates how to build a complete task manager application with zero backend using Dev Proxy. It showcases Dev Proxy's full value proposition by combining multiple plugins to create a realistic development environment that runs entirely offline. + +The sample includes: +- **CrudApiPlugin** - Full CRUD API with in-memory data store for tasks +- **AuthPlugin** - API key authentication to secure the API +- **LatencyPlugin** - Realistic response time simulation (200-800ms) +- **DevToolsPlugin** - Chrome DevTools integration for debugging + + + +## Compatibility + + + +## Contributors + +- [Waldek Mastykarz](https://github.com/waldekmastykarz) + +## Version history + +Version|Date|Comments +-------|----|-------- +1.0.0|January 19, 2026|Initial release + +## Prerequisites + +- [Dev Proxy](https://aka.ms/devproxy) +- [Node.js LTS](https://nodejs.org) (for http-server) + +## 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/full-stack-no-backend) and unzip it) +- Navigate to the sample folder: `cd samples/full-stack-no-backend` +- Run `npm install` to install dependencies +- Run `npm start` to start Dev Proxy and the web server +- Open http://localhost:3000 in your browser +- The app auto-connects using the default API key (`dev-proxy-demo-key`) + +## Architecture + +``` +┌─────────────────┐ ┌─────────────────────────────────────┐ +│ │ │ Dev Proxy │ +│ Frontend │ │ ┌─────────────────────────────┐ │ +│ (Browser) │────▶│ │ LatencyPlugin │ │ +│ │ │ │ (200-800ms delay) │ │ +│ index.html │ │ └─────────────┬───────────────┘ │ +│ │ │ │ │ +└─────────────────┘ │ ┌─────────────▼───────────────┐ │ + │ │ AuthPlugin │ │ + │ │ (API key validation) │ │ + │ └─────────────┬───────────────┘ │ + │ │ │ + │ ┌─────────────▼───────────────┐ │ + │ │ CrudApiPlugin │ │ + │ │ (in-memory data store) │ │ + │ └─────────────┬───────────────┘ │ + │ │ │ + │ ┌─────────────▼───────────────┐ │ + │ │ DevToolsPlugin │ │ + │ │ (Chrome DevTools) │ │ + │ └─────────────────────────────┘ │ + └─────────────────────────────────────┘ +``` + +## Features + +This sample illustrates the following concepts: + +### Complete CRUD API +- **GET /tasks** - Retrieve all tasks +- **GET /tasks/{id}** - Retrieve a single task +- **POST /tasks** - Create a new task +- **PATCH /tasks/{id}** - Update a task +- **DELETE /tasks/{id}** - Delete a task + +### API Key Authentication +- Requests must include `x-api-key: dev-proxy-demo-key` header +- Invalid keys return 401 Unauthorized + +### Realistic Latency +- All responses are delayed by 200-800ms +- Simulates real-world network conditions +- Latency is displayed in the UI + +### DevTools Integration +- Opens Chrome DevTools automatically +- View all intercepted requests and responses +- Debug API calls in real-time + +### Vanilla JavaScript Frontend +- No framework dependencies +- Full task management UI +- Real-time status updates +- Responsive design + +## Why this approach? + +1. **Ship MVPs without backend team** - Start building your frontend immediately +2. **Complete offline development** - No internet required, works anywhere +3. **Realistic testing** - Latency and authentication behave like production +4. **Easy debugging** - DevTools integration shows exactly what's happening +5. **Single tool solution** - Everything runs through Dev Proxy + +## 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%20full-stack-no-backend%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.** + + diff --git a/samples/full-stack-no-backend/assets/sample.json b/samples/full-stack-no-backend/assets/sample.json new file mode 100644 index 0000000..0391cf7 --- /dev/null +++ b/samples/full-stack-no-backend/assets/sample.json @@ -0,0 +1,87 @@ +[ + { + "name": "pnp-devproxy-full-stack-no-backend", + "source": "pnp", + "title": "Build complete app with zero backend", + "shortDescription": "Demonstrates building a complete task manager application with zero backend using Dev Proxy. Features a vanilla JavaScript frontend with full CRUD operations, API key authentication, realistic latency simulation, and Chrome DevTools integration.", + "url": "https://github.com/pnp/proxy-samples/tree/main/samples/full-stack-no-backend", + "downloadUrl": "https://pnp.github.io/download-partial/?url=https://github.com/pnp/proxy-samples/tree/main/samples/full-stack-no-backend", + "longDescription": [ + "Demonstrates building a complete task manager application with zero backend using Dev Proxy. Features a vanilla JavaScript frontend with full CRUD operations, API key authentication, realistic latency simulation, and Chrome DevTools integration." + ], + "creationDateTime": "2026-01-10", + "updateDateTime": "2026-01-19", + "products": [ + "Dev Proxy" + ], + "metadata": [ + { + "key": "SAMPLE ID", + "value": "full-stack-no-backend" + }, + { + "key": "PRESET", + "value": "No" + }, + { + "key": "MOCKS", + "value": "No" + }, + { + "key": "PLUGIN", + "value": "No" + }, + { + "key": "PROXY VERSION", + "value": "v2.1.0" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://github.com/pnp/proxy-samples/raw/main/samples/full-stack-no-backend/assets/screenshot.png", + "alt": "Task Manager app running with Dev Proxy" + } + ], + "authors": [ + { + "gitHubAccount": "waldekmastykarz", + "pictureUrl": "https://github.com/waldekmastykarz.png", + "name": "Waldek Mastykarz" + } + ], + "references": [ + { + "name": "Simulate a CRUD API", + "description": "Learn how to use the Dev Proxy to simulate a CRUD API.", + "url": "https://learn.microsoft.com/microsoft-cloud/dev/dev-proxy/how-to/simulate-crud-api" + }, + { + "name": "CrudApiPlugin documentation", + "description": "Technical reference for the CrudApiPlugin.", + "url": "https://learn.microsoft.com/microsoft-cloud/dev/dev-proxy/technical-reference/crudapiplugin" + }, + { + "name": "AuthPlugin documentation", + "description": "Technical reference for the AuthPlugin.", + "url": "https://learn.microsoft.com/microsoft-cloud/dev/dev-proxy/technical-reference/authplugin" + }, + { + "name": "LatencyPlugin documentation", + "description": "Technical reference for the LatencyPlugin.", + "url": "https://learn.microsoft.com/microsoft-cloud/dev/dev-proxy/technical-reference/latencyplugin" + }, + { + "name": "DevToolsPlugin documentation", + "description": "Technical reference for the DevToolsPlugin.", + "url": "https://learn.microsoft.com/microsoft-cloud/dev/dev-proxy/technical-reference/devtoolsplugin" + }, + { + "name": "Get started with the Dev Proxy", + "description": "The tutorial will introduce you to the Dev Proxy and show you how to use its features.", + "url": "https://learn.microsoft.com/microsoft-cloud/dev/dev-proxy/get-started" + } + ] + } +] diff --git a/samples/full-stack-no-backend/assets/screenshot.png b/samples/full-stack-no-backend/assets/screenshot.png new file mode 100644 index 0000000..4b0ac78 Binary files /dev/null and b/samples/full-stack-no-backend/assets/screenshot.png differ diff --git a/samples/full-stack-no-backend/index.html b/samples/full-stack-no-backend/index.html new file mode 100644 index 0000000..ae65e67 --- /dev/null +++ b/samples/full-stack-no-backend/index.html @@ -0,0 +1,604 @@ + + +
+ + +A complete app with zero backend - powered by Dev Proxy
+