Mock REST APIs like standard JSONPlaceholder are great for quick hello-world prototypes. But as soon as your frontend app grows to test GraphQL queries, JWT authentication flows, custom domain entities (like products or orders), or TypeScript auto-completion, standard mock tools quickly hit a brick wall.
A while ago, I launched Playground APIβa zero-config, stateful mock API that solved the biggest flaw in mock testing: instant state loss. Playground API introduced zero-login per-session sandboxing, giving frontend developers real state persistence for POST, PUT, PATCH, and DELETE requests without databases or authentication logins.
Following our v2 update (which brought network latency simulation, error injection, and OpenAPI exports), today Iβm thrilled to introduce Playground API v3.0! β‘
v3.0 elevates Playground API from a mock REST API into a complete multi-protocol developer testing ecosystem featuring a GraphQL Sandbox Gateway, Fake JWT Auth Simulation, Dynamic Custom Collections, Dynamic SVG Avatars, and Full TypeScript SDK Definitions.
π Whatβs New in Playground API v3.0?
πΈοΈ 1. GraphQL Sandbox Gateway (/graphql)
You no longer need to spin up a mock GraphQL server or setup Apollo Server locally just to test GraphQL queries and mutations.
Playground API now includes a native GraphQL Gateway at /graphql. Crucially, all GraphQL mutations (createPost, updatePost, deletePost) interact directly with your session sandbox overlayβgiving you stateful GraphQL testing out-of-the-box!
GraphQL Query Example:
query GetUserWithPostsAndComments {
user(id: 1) {
name
email
avatar
posts {
id
title
comments {
id
body
}
}
}
}
GraphQL Stateful Mutation Example:
mutation AddNewPost {
createPost(
user_id: 1,
title: "\"Testing GraphQL Mutations in Playground API v3\", "
body: "Stateful GraphQL without any backend setup!"
) {
id
title
user {
name
}
}
}
π 2. Fake JWT Authentication Simulation (/auth)
Testing login screens, token storage (localStorage / HTTP-only cookies), token refresh cycles, and protected profile views is historically tedious with fake APIs.
Playground API v3 introduces a dedicated JWT Auth Simulation:
- πͺ
POST /auth/login: Authenticate using mock credentials and receive signed JWT access and refresh tokens. - π
POST /auth/register: Register a new sandboxed user profile with instant JWT credential generation. - π
POST /auth/refresh: Test access token expiration and token rotation. - π€
GET /auth/me&PATCH /auth/me: Fetch and edit the logged-in user profile passingAuthorization: Bearer <jwt_token>.
// 1. Login to get JWT tokens
const loginRes = await fetch('https://playground-api-xi.vercel.app/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'Bret' })
});
const { access_token } = await loginRes.json();
// 2. Fetch authenticated profile
const profileRes = await fetch('https://playground-api-xi.vercel.app/auth/me', {
headers: { 'Authorization': `Bearer ${access_token}` }
});
const user = await profileRes.json();
π¦ 3. Dynamic Custom Resource Collections (/custom/:collection)
Why limit mock testing to posts, users, comments, and todos? What if you're building an e-commerce dashboard (products, orders), a CRM (leads, contacts), or a note-taking app (notes)?
With Dynamic Custom Collections, you can hit any custom endpoint name on the fly:
-
POST /custom/productsβ Creates a new product entity in your session overlay -
GET /custom/productsβ Fetches your sandboxed product collection -
PUT /custom/products/local-123β Updates the custom entity -
DELETE /custom/products/local-123β Deletes the custom entity
You can also seed entire mock domains in 1 click via POST /custom/seed!
πΌοΈ 4. Built-in Dynamic SVG Avatars & Image Placeholders (/public/avatars/:seed)
Say goodbye to broken external image placeholder URLs or slow Unsplash requests in your UI components!
Playground API now serves crisp, ultra-fast dynamic SVG avatar and thumbnail placeholders directly:
- π€ Avatar:
/public/avatars/john_doe.svg?bg=4f46e5&size=128 - πΌοΈ Thumbnail:
/public/thumbnails/product_1.svg?bg=10b981&width=400&height=200
π 5. Full TypeScript Definitions & SDK Types (/types/ts)
Stop manually writing TypeScript interfaces for your mock data! Playground API now exposes native .d.ts definitions:
- Download directly at
/downloads/playground-api.d.tsor view live at/types/ts. - Easily import
User,Post,Comment,Todo,AuthPayload,SessionStats, and endpoint response wrappers straight into your TypeScript codebase.
πΎ 6. Session Snapshot Export & Import (JSON)
Want to share a specific mock bug state with a teammate or seed your Playwright/Cypress test runner with pre-configured data?
- π€
GET /session/export: Export your entire session sandbox overlay as a clean, shareable.jsonsnapshot file. - π₯
POST /session/import: Import a saved JSON snapshot to instantly restore pre-set data states.
ποΈ 7. Decoupled Architecture (playground_api_fe & playground_api_be)
Under the hood, Playground API has been re-architected into a fully decoupled architecture:
- π¨ Frontend Portal (
playground_api_fe): EJS template design system, interactive Try-It API Studio, GraphQL Explorer, and documentation UI. - βοΈ Backend API (
playground_api_be): Lightweight, high-performance Node.js / Express 5 & Prisma ORM service powering session virtual merging.
βοΈ Updated React Example: Combining GraphQL, JWT Auth & Latency Simulation
Hereβs a full React example demonstrating how easily you can test JWT Login, GraphQL Queries, and Stateful Mutations in a single component:
import React, { useState } from 'react';
const API_BASE = 'https://playground-api-xi.vercel.app';
export default function PlaygroundV3Demo() {
const [token, setToken] = useState(null);
const [user, setUser] = useState(null);
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(false);
// 1. Simulate JWT Auth Login
const handleLogin = async () => {
const res = await fetch(`${API_BASE}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'Bret' })
});
const data = await res.json();
setToken(data.access_token);
setUser(data.user);
};
// 2. Fetch Data via GraphQL Gateway
const fetchGraphQLData = async () => {
setLoading(true);
const query = `
query {
posts(limit: 5) {
id
title
user { name email }
}
}
`;
const res = await fetch(`${API_BASE}/graphql`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query })
});
const { data } = await res.json();
setPosts(data.posts);
setLoading(false);
};
return (
<div style={{ maxWidth: '650px', margin: '40px auto', fontFamily: 'system-ui, sans-serif' }}>
<h2>π Playground API v3 β Developer Test Rig</h2>
<div style={{ display: 'flex', gap: '10px', marginBottom: '20px' }}>
{!token ? (
<button onClick={handleLogin} style={{ padding: '8px 16px', background: '#4f46e5', color: '#fff', border: 'none', borderRadius: '6px' }}>
π Test JWT Login (`/auth/login`)
</button>
) : (
<p style={{ color: 'green' }}>β
Authenticated as <strong>{user?.name}</strong></p>
)}
<button onClick={fetchGraphQLData} style={{ padding: '8px 16px', background: '#059669', color: '#fff', border: 'none', borderRadius: '6px' }}>
πΈοΈ Fetch via GraphQL (`/graphql`)
</button>
</div>
{loading && <p>β³ Querying GraphQL Gateway...</p>}
{posts.length > 0 && (
<div>
<h3>π GraphQL Posts Result:</h3>
<ul>
{posts.map((p) => (
<li key={p.id}>
<strong>{p.title}</strong> β <small>By {p.user?.name}</small>
</li>
))}
</ul>
</div>
)}
</div>
);
}
π Complete Feature Matrix: v1 vs v2 vs v3
| Feature | v1.0 Baseline | v2.0 Testing Suite | π v3.0 Next-Gen Ecosystem |
|---|---|---|---|
| Stateful Per-Session Sandbox | β Cookie / Header | β Cookie / Header | β Cookie / Header |
| REST Data Endpoints | β 4 Baseline Collections | β 4 Baseline Collections | β
Baseline + Custom Collections (/custom/*) |
| GraphQL Gateway | β None | β None | β
Stateful /graphql Queries & Mutations |
| JWT Auth Simulation | β None | β None | β
/auth/login, /auth/register, /auth/me
|
| Dynamic Custom Entities | β Fixed Collections | β Fixed Collections | β
/custom/:collection (Products, Orders, etc.) |
| Dynamic SVG Image Helpers | β None | β None | β
/public/avatars/* & /public/thumbnails/*
|
| TypeScript Definitions | β None | β None | β
.d.ts export & /types/ts endpoint |
| Session Snapshot Import/Export | β None | β Reset Only | β
JSON Export & Import (/session/export) |
| Network Latency & Error Injection | β None | β
?_delay & ?_status
|
β
?_delay & ?_status
|
| Schema Downloads | β None | β OpenAPI, Postman, Bruno | β OpenAPI, Postman, Bruno, GraphQL SDL |
π Try It Out & Get Involved!
Playground API is 100% free, zero-config, open-source, and requires no account setup:
π Live App & Interactive API Studio: https://playground-api-xi.vercel.app/
π Interactive Developer Portal: https://playground-api-xi.vercel.app/docs
πΈοΈ GraphQL Gateway Docs: https://playground-api-xi.vercel.app/docs/graphql
β GitHub Repository: github.com/nileshcodehub/playground_api
If Playground API makes your frontend development, GraphQL prototyping, or E2E testing easier, drop a β on GitHub!
Which v3 feature are you most excited to try in your projects? Let me know in the comments below! π
Top comments (0)