Postman Runtime

repository·develop·Indexed 42 days ago

https://github.com/postmanlabs/postman-runtime

A low-level JavaScript library that provides the core execution engine for Postman collections, handling request sending, script execution, and variable scoping. It serves as the underlying technology for the Postman App, Postman Monitoring, and Newman. Version 7.56.1.

Tokens
16.4K
Snippets
44
Records
67
Agent score
54%

What's inside Postman Runtime

  1. Overview of Postman Runtime

    develop

    Postman Runtime is a low-level library that serves as the core engine for collection execution and request sending. It is used as the backbone for the Postman App, Postman Monitoring, and Newman.

    Note: This is a low-level library. If your goal is to execute Postman collections in a high-level manner, you should use Newman instead.

  2. What is Protocol Profile Behavior

    develop

    Protocol Profile Behavior is a set of configurations used to alter how requests are sent. By defining these behaviors, you can ensure a collection behaves consistently across different execution agents, removing dependency on agent-specific settings.

    These configurations can be defined at two levels within a collection:

    1. Item level: Applies to a specific request.
    2. ItemGroup level: Applies to a group of requests and is inherited by items within that group.
    3. Collection level: Applies to all items within the collection.
  3. How the Postman Runtime components work together

    develop

    Postman Runtime is composed of several major components that manage different stages of a collection run:

    • Runner: Initializes the run by sanitizing the input collection, extracting Items, and preparing iteration data. It produces a Run object.
    • Run: The central handle for controlling a collection run. It maintains the entire state (current request, pending requests, current iteration) and provides methods to pause, resume, or abort the run. It also allows looking up an Item via its Cursor.
    • Cursor: Represents the current position within the collection run. It treats the collection as a 2D array (iterations × requests). Every trigger called during an Item execution receives the current Cursor as an argument.
    • Requester: The component responsible for the actual HTTP execution, including sending requests, managing the cookie store, and adding request metadata. It can be configured for behaviors like SSL verification or redirect handling.
  4. Use Triggers to interact with the Runtime lifecycle

    develop

    Triggers are the primary interface for interacting with the Runtime from the outside world. When starting a Run, you can provide a set of trigger functions that the Runtime calls at specific lifecycle events.

    Common Triggers:

    • start: Called when the runtime is ready to begin a new run, but before the run actually starts.
    • beforeRequest: Called before a request is sent. It provides information about the final request, including resolved variables and authentication handlers.

    Refer to the main README for a complete list of supported triggers.

  5. Understand the Request Flow and Requester

    develop

    The Runtime uses a Requester to send requests. While currently supporting HTTP, the architecture allows for other protocols like Websocket or FTP.

    The HTTP Requester: Accepts an Item and returns the response, cookies, and the sent request. It automatically handles extra headers like User-Agent.

    Request Control Flow Steps:

    1. Variable Resolution
    2. Signing the request (authentication)
    3. Reading file attachments
    4. Proxy lookup (if required)
    5. Loading client-side SSL certificates
    6. Sending the request
    7. Determining if a replay is necessary (auth-driven)
    8. Replaying the request
  6. Understanding the Cursor and its `ref` property

    develop

    A Cursor points to a unique request within the collection's execution grid (where rows are iterations and columns are requests).

    Every Cursor contains a ref property, which is a unique UUID. This ref is unique to each specific item execution; even if the same request is executed in different iterations, each instance will have a different ref. The ref is updated whenever the runtime moves to a new request, including when using postman.setNextRequest() in the sandbox.

  7. How the Postman Runtime queue-command architecture works

    develop

    Postman Runtime uses a queue-command based architecture. Commands are added to a queue and processed sequentially. At any given time, only one command is running, though a single command may execute multiple tasks in parallel.

    Key characteristics:

    • Command Composition: Commands can queue other commands (e.g., an item command queues prerequest, request, and test commands).
    • Queue Manipulation: Commands have the ability to manipulate the queue by adding new commands or interrupting the existing queue.
    • Command Interface: Each command accepts a payload and a callback (conventionally named next()) which must be called when the command is complete.
  8. Understand the cursor and assertion objects

    develop

    The cursor object is passed to most lifecycle hooks to provide context about the current execution state.

    Cursor properties:

    • position: Number
    • iteration: Number
    • length: Number
    • cycles: Number
    • eof: Boolean
    • empty: Boolean
    • bof: Boolean
    • cr: Boolean
    • ref: String
    • scriptId: String
    • eventId: String

    Assertion object properties (passed to the assertion hook):

    • error: Error
    • index: Number
    • name: String
    • skipped: Number
    • passed: Number
  9. Implement new authentication mechanisms via Authorizer

    develop

    The Authorizer controls the request flow, specifically deciding if a request was successfully signed and whether it needs to be replayed.

    To add a new authentication mechanism, you must implement the AuthHandlerInterface, which provides the following hooks:

    • pre: Logic to run before the authentication process.
    • init: Initialization logic.
    • sign: The logic used to sign the request.
    • post: Logic to run after the signing process.

    Supported Authentication Types:

    • Basic
    • Digest
    • AWS Signature
    • OAuth-1
    • OAuth-2
    • Hawk
    • NTLM
  10. Run a Postman Collection with `runtime.Runner`

    develop

    To execute a collection, instantiate a runtime.Runner and call its .run() method. The .run() method requires a collection object (typically constructed via the Postman Collection SDK) and an options object to configure the execution environment. The execution is asynchronous and accepts a callback function that provides a run object to start the process.

    Basic usage pattern:

    1. Import postman-runtime.
    2. Create a new runtime.Runner().
    3. Provide a collection and an options object to runner.run().
    4. Use the provided run object to call .start(callbacks).
    var runtime = require('postman-runtime');
    var sdk = require('postman-collection-sdk'); // Assumed SDK import
    
    var runner = new runtime.Runner();
    var collection = new sdk.Collection();
    
    runner.run(collection, { /* options */ }, function (err, run) {
        console.log('Created a new Run!');
        // run.start(callbacks) follows here
    });
  11. How to add a new authentication mechanism to Postman Runtime

    develop

    To implement a custom authentication mechanism in the Postman Runtime, create a new JavaScript file in the postman-runtime/lib/authorizer/ directory. Each authentication module must export an object containing four specific lifecycle hooks: pre, init, post, and sign. These hooks allow you to verify credentials, fetch required parameters (like challenges), handle re-authentication after a 401 response, and finally sign the request with headers.

    module.exports = {
        pre: function (context, requester, done) {
            done(null, true);
        },
     
        init: function (context, requester, done) {
            done(null);
        },
    
        post: function (context, requester, done) {
            done(null, true);
        },
    
        sign: function (params, request) {
            return request;
        }
    };
  12. Use callbacks to monitor collection execution

    develop

    When calling runner.run(), you can provide a callback function that receives a run object. By calling run.start(), you can pass an object containing various lifecycle hooks (callbacks). These hooks allow you to intercept and react to different stages of the collection execution, such as when a request starts, when an assertion is made, or when an error occurs.

    Common use cases include logging progress, capturing test results, monitoring network IO, or handling exceptions during the run.

    runner.run(collection, { /* options */ }, function(err, run) {
        run.start({
            start: function (err, cursor) { /* ... */ },
            assertion: function (cursor, assertions) { /* ... */ },
            done: function (err) { /* ... */ },
            // ... other lifecycle hooks
        });
    });