Skip to content

Add Postman Collection import command#4

Merged
vedssharma merged 1 commit intomainfrom
claude/cli-postman-export-nIoon
Mar 16, 2026
Merged

Add Postman Collection import command#4
vedssharma merged 1 commit intomainfrom
claude/cli-postman-export-nIoon

Conversation

@vedssharma
Copy link
Copy Markdown
Owner

Adds apicli import postman <file> to load a Postman Collection v2.0/v2.1 JSON file and save all its requests as an apicli collection.

Key details:

  • Handles both URL formats: plain string and structured object
  • Recursively flattens nested folders using "Folder / Request" prefixes
  • Appends to an existing collection if the name already exists
  • --collection flag overrides the Postman collection name as the target
  • Skips non-raw body modes (form-data, urlencoded) gracefully

https://claude.ai/code/session_01PyL8EW4HoiuaCszqviyfGt

Adds `apicli import postman <file>` to load a Postman Collection v2.0/v2.1
JSON file and save all its requests as an apicli collection.

Key details:
- Handles both URL formats: plain string and structured object
- Recursively flattens nested folders using "Folder / Request" prefixes
- Appends to an existing collection if the name already exists
- --collection flag overrides the Postman collection name as the target
- Skips non-raw body modes (form-data, urlencoded) gracefully

https://claude.ai/code/session_01PyL8EW4HoiuaCszqviyfGt
@vedssharma vedssharma merged commit 4963802 into main Mar 16, 2026
1 check passed
@vedssharma vedssharma deleted the claude/cli-postman-export-nIoon branch March 16, 2026 04:12
@claude
Copy link
Copy Markdown

claude Bot commented Mar 16, 2026

Code Review: Add Postman Collection import command

Overall this is a solid implementation. The polymorphic URL handling with json.RawMessage is exactly right for Postman's v2.0/v2.1 compatibility requirement, and the recursive folder flattening is clean and readable. A few issues worth addressing:


Bug: Disabled headers are imported as active

postmanHeader has no disabled field, so headers marked disabled in Postman will be silently imported and sent on every request.

// Current
type postmanHeader struct {
    Key   string `json:"key"`
    Value string `json:"value"`
}

// Should be
type postmanHeader struct {
    Key      string `json:"key"`
    Value    string `json:"value"`
    Disabled bool   `json:"disabled"`
}

// And in convertPostmanRequest:
for _, h := range pr.Header {
    if h.Key != "" && !h.Disabled {
        headers[h.Key] = h.Value
    }
}

Performance: One transaction per request

runImportPostman calls store.AddToCollection() in a loop, and each call opens its own transaction. For large Postman collections this will be noticeably slow. Consider batching the inserts into a single transaction, or adding a AddManyToCollection(name string, reqs []model.SavedRequest) error method on the storage layer.


Minor: Query params dropped in URL reconstruction fallback

In resolvePostmanURL, when falling back to reconstructing the URL from parts, query params are not included:

// port and query params are both missing from the fallback
return fmt.Sprintf("%s://%s%s", scheme, host, path)

In practice Postman always populates raw, so this is a low-risk edge case, but worth a // Note: query params and port not reconstructed comment so future readers don't wonder.


Minor: Misleading #nosec comment

data, err := os.ReadFile(filePath) // #nosec G304 – path comes from CLI argument, not user-controlled input

CLI arguments are user-controlled; the suppression is valid, but the rationale should be "intentional user-supplied path" rather than "not user-controlled."


No tests

The repo has no test files at all, so this isn't a regression, but flattenPostmanItems and resolvePostmanURL are pure functions that are easy to unit-test and cover important edge cases (deeply nested folders, string vs object URL, missing URL, disabled headers). These would be good candidates for the project's first _test.go.


Positive notes

  • The json.RawMessage approach for the polymorphic URL field is the right call and avoids a custom UnmarshalJSON.
  • Appending to an existing collection rather than overwriting is the right UX default.
  • Partial-import error handling (continue + count) is consistent with the rest of the codebase.
  • The --collection flag to override the target name is a useful escape hatch.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants