Skip to content

Implement Collections & Request Saving (Postman-like functionality) #14

@aadityansha06

Description

@aadityansha06

Feature Description

Add ability to save HTTP requests into organized collections, similar to Postman's collection feature. This will allow users to:

  • Save frequently used API requests
  • Organize requests into logical collections
  • Quickly load and execute saved requests
  • Share collections with team members

Motivation

Currently, users need to re-enter request details (URL, headers, body, auth) every time they want to make the same API call. This is time-consuming and error-prone, especially when working with complex APIs or multiple environments (dev/staging/prod).

For Flash CLI to be production-ready and competitive with Postman, users need a way to persist and organize their requests.

Proposed Solution

File Structure

~/.flash/
├── config.json                 # Global settings
├── collections.json            # Index of all collections
├── environments.json           # Environment variables (dev/staging/prod)
├── history.json               # Request history (last 50 requests)
└── collections/               # Saved collections
├── github_api/
│   ├── .meta.json        # Collection metadata
│   ├── get_user.json     # Individual saved request
│   ├── list_repos.json
│   └── create_issue.json
├── weather_api/
│   ├── .meta.json
│   └── get_forecast.json
└── payment_api/
├── .meta.json
├── create_order.json
└── process_payment.json

Feature Description

Add ability to save HTTP requests into organized collections, similar to Postman's collection feature. This will allow users to:

  • Save frequently used API requests
  • Organize requests into logical collections
  • Quickly load and execute saved requests
  • Share collections with team members

Motivation

Currently, users need to re-enter request details (URL, headers, body, auth) every time they want to make the same API call. This is time-consuming and error-prone, especially when working with complex APIs or multiple environments (dev/staging/prod).

For Flash CLI to be production-ready and competitive with Postman, users need a way to persist and organize their requests.

Proposed Solution

File Structure

~/.flash/
├── config.json                 # Global settings
├── collections.json            # Index of all collections
├── environments.json           # Environment variables (dev/staging/prod)
├── history.json               # Request history (last 50 requests)
└── collections/               # Saved collections
    ├── github_api/
    │   ├── .meta.json        # Collection metadata
    │   ├── get_user.json     # Individual saved request
    │   ├── list_repos.json
    │   └── create_issue.json
    ├── weather_api/
    │   ├── .meta.json
    │   └── get_forecast.json
    └── payment_api/
        ├── .meta.json
        ├── create_order.json
        └── process_payment.json

Core Features

1. Collections Management

  • Create Collection: Create a new collection with name and description
  • List Collections: View all saved collections with request count
  • Delete Collection: Remove a collection and all its requests
  • Rename Collection: Update collection name/description
  • Import/Export: Share collections as JSON files

2. Request Saving

  • Save Request: After executing a request, prompt to save it
  • Auto-save: Optionally auto-save all successful requests
  • Save to Existing: Add request to existing collection
  • Save to New: Create new collection while saving
  • Request Metadata: Store name, tags, notes, timestamp

3. Request Loading

  • Browse Collections: Navigate through collections and requests
  • Quick Load: Load and execute saved request with one command
  • Search: Find requests by name, URL, method, or tags
  • Recent Requests: Quick access to recently used requests

4. Environment Variables

  • Multi-Environment: Support dev/staging/prod environments
  • Variable Substitution: Use {{BASE_URL}}, {{API_KEY}} in requests
  • Environment Switching: Switch between environments easily
  • Secure Storage: Mask sensitive values (API keys, tokens)

5. Request History

  • Track Requests: Save last 50 requests automatically
  • View History: List recent requests with status codes
  • Quick Re-run: Re-execute any historical request
  • History Details: Show response time, status, timestamp

User Workflows

Workflow 1: First-time Save

User: Makes a GET request to https://api.github.com/users/johndoe
Flash: ✅ Request successful! (200 OK, 245ms)

Flash: Would you like to save this request? [Y/N]: Y

Flash: Select option:
       1. Save to existing collection
       2. Create new collection

User: 2

Flash: Enter collection name: GitHub API
Flash: Enter description (optional): GitHub REST API v3 requests

Flash: Enter request name: Get User Profile
Flash: Add tags (comma-separated, optional): users, profile, public

Flash: ✅ Saved to collection "GitHub API"
       Location: ~/.flash/collections/github_api/get_user_profile.json

Workflow 2: Loading Saved Request

User: Selects "Collections" from main menu

Flash: Your Collections:
       ┌──────────────────────────────────────┐
       │ 1. GitHub API        (3 requests)    │
       │    Created: 2025-01-15               │
       │                                      │
       │ 2. Weather API       (1 request)     │
       │    Created: 2025-01-20               │
       │                                      │
       │ 3. Payment API       (5 requests)    │
       │    Created: 2025-01-22               │
       └──────────────────────────────────────┘

User: 1

Flash: GitHub API Requests:
       ┌──────────────────────────────────────┐
       │ 1. GET Get User Profile              │
       │    https://api.github.com/users/...  │
       │    Tags: users, profile              │
       │                                      │
       │ 2. GET List Repositories             │
       │    https://api.github.com/users/.../repos │
       │                                      │
       │ 3. POST Create Issue                 │
       │    https://api.github.com/repos/.../issues │
       └──────────────────────────────────────┘

User: 1

Flash: Loading "Get User Profile"...
       GET https://api.github.com/users/johndoe
       🚀 Executing request...
       
       ✅ 200 OK (234ms)
       [Response displayed]

Workflow 3: Using Environment Variables

User: Saves request with URL: {{BASE_URL}}/api/users

Flash: Environments:
       ● Development  BASE_URL: http://localhost:3000
       ○ Staging      BASE_URL: https://staging.api.company.com
       ○ Production   BASE_URL: https://api.company.com

User: Switches to "Staging"

Flash: Active environment: Staging
       Request will use: https://staging.api.company.com/api/users

JSON Data Structures

collections.json (Index)

{
  "version": "1.0.0",
  "last_updated": "2025-01-30T10:30:00Z",
  "collections": [
    {
      "id": "github_api_1706612400",
      "name": "GitHub API",
      "folder": "github_api",
      "description": "GitHub REST API v3 requests",
      "created_at": "2025-01-15T10:30:00Z",
      "updated_at": "2025-01-30T09:15:00Z",
      "request_count": 3,
      "tags": ["github", "rest", "public-api"]
    }
  ]
}

Individual Request File (get_user.json)

{
  "id": "get_user_1706612500",
  "name": "Get User Profile",
  "method": "GET",
  "url": "https://api.github.com/users/{{username}}",
  "headers": [
    {
      "key": "Authorization",
      "value": "Bearer {{GITHUB_TOKEN}}",
      "enabled": true
    },
    {
      "key": "Accept",
      "value": "application/vnd.github.v3+json",
      "enabled": true
    }
  ],
  "body": null,
  "body_type": null,
  "auth": {
    "type": "bearer",
    "token": "{{GITHUB_TOKEN}}"
  },
  "saved_at": "2025-01-15T10:35:00Z",
  "last_executed": "2025-01-30T09:15:00Z",
  "tags": ["users", "profile", "public"],
  "notes": "Fetches public GitHub user profile information. Requires valid username parameter."
}

environments.json

{
  "version": "1.0.0",
  "active": "development",
  "environments": [
    {
      "id": "development",
      "name": "Development",
      "variables": [
        {
          "key": "BASE_URL",
          "value": "http://localhost:3000",
          "enabled": true
        },
        {
          "key": "API_KEY",
          "value": "dev_key_12345",
          "enabled": true,
          "secret": true
        }
      ]
    },
    {
      "id": "staging",
      "name": "Staging",
      "variables": [
        {
          "key": "BASE_URL",
          "value": "https://staging.api.company.com",
          "enabled": true
        },
        {
          "key": "API_KEY",
          "value": "staging_key_67890",
          "enabled": true,
          "secret": true
        }
      ]
    },
    {
      "id": "production",
      "name": "Production",
      "variables": [
        {
          "key": "BASE_URL",
          "value": "https://api.company.com",
          "enabled": true
        },
        {
          "key": "API_KEY",
          "value": "prod_key_abcdef",
          "enabled": true,
          "secret": true
        }
      ]
    }
  ]
}

history.json

{
  "version": "1.0.0",
  "max_entries": 50,
  "requests": [
    {
      "id": "history_1706699400",
      "method": "GET",
      "url": "https://api.github.com/users/johndoe",
      "status_code": 200,
      "response_time_ms": 245,
      "timestamp": "2025-01-30T10:30:00Z",
      "collection_id": "github_api_1706612400",
      "request_id": "get_user_1706612500"
    },
    {
      "id": "history_1706699350",
      "method": "POST",
      "url": "https://api.example.com/login",
      "status_code": 200,
      "response_time_ms": 180,
      "timestamp": "2025-01-30T10:29:10Z",
      "collection_id": null,
      "request_id": null
    }
  ]
}

Implementation Phases

Phase 1: Basic Save/Load (MVP)

  • Create ~/.flash/ directory structure
  • Implement collections.json index
  • Save request to file after execution
  • Load and execute saved request
  • List all collections
  • List requests in a collection

Phase 2: Collections Management

  • Create new collection
  • Delete collection
  • Rename collection
  • Add request to existing collection
  • Delete request from collection
  • Search requests by name/URL

Phase 3: Environment Variables

  • Create environments.json
  • Define environments (dev/staging/prod)
  • Variable substitution in URL/headers/body
  • Switch active environment
  • Mask secret variables in UI

Phase 4: Request History

  • Create history.json
  • Auto-save all requests to history
  • Display recent requests
  • Quick re-run from history
  • Clear history option

Phase 5: Advanced Features

  • Import/Export collections
  • Request templates
  • Duplicate request
  • Request notes/documentation
  • Tags and filtering
  • Collection-level auth settings

Technical Considerations

File Operations

  • Use fopen(), fread(), fwrite() for file I/O
  • Parse JSON using existing code or add lightweight JSON parser
  • Handle file permissions (create with 0600 for sensitive data)
  • Implement file locking for concurrent access

Error Handling

  • Gracefully handle corrupted JSON files
  • Validate collection/request IDs before operations
  • Check directory permissions
  • Provide helpful error messages

Security

  • Mask sensitive values (API keys, tokens) in UI
  • Store secrets with restricted permissions (0600)
  • Consider encryption for sensitive data (future)
  • Warn users before saving credentials

Performance

  • Lazy load collections (don't load all at startup)
  • Cache collections.json in memory
  • Index requests by ID for quick lookup
  • Limit history to 50-100 entries

Alternative Approaches Considered

SQLite Database

Pros: Better querying, transactions, performance at scale
Cons: Additional dependency, less human-readable, harder to share

Decision: Start with JSON files for simplicity, migrate to SQLite later if needed.

Single JSON File vs Multiple Files

Pros (Single): Simpler, atomic writes, easier to share
Cons (Single): Doesn't scale, harder to version control individual requests

Decision: Use multiple files (one per request) for Git-friendliness and scalability.

Additional Context

Similar Tools Comparison

Feature Postman Insomnia HTTPie Flash (Proposed)
Collections
Environments
Request History
CLI-based
Lightweight
No Electron
Code Generation ✅ (already has)

Success Metrics

  • Users can save and reload requests in < 5 seconds
  • Collections can handle 100+ requests without performance issues
  • Environment switching takes < 1 second
  • Zero data loss on corrupt JSON (graceful fallback)

Questions/Discussion

  1. Should we support nested folders within collections?
  2. Should environment variables support computed values (e.g., {{timestamp}})?
  3. Should we auto-backup collections before destructive operations?
  4. Should we support importing Postman collections (v2.1 format)?
  5. Should collection metadata include shared auth/headers?

References

Implementation Help Needed

  • JSON parsing library recommendation (or use existing code?)
  • File locking strategy for concurrent access
  • Variable substitution algorithm (regex vs simple string replace?)
  • UI/UX feedback on proposed workflows

Labels

enhancement, feature-request, collections, save-requests, high-priority, help-wanted

Assignees

@aadityansha06

Milestone

v2.0.0 - Collections & Save Feature

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions