npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

prism-fid-http

v0.0.5

Published

This package provides a HTTP client featuring the ability to:

Downloads

1,130

Readme

HTTP Client

This package provides a HTTP client featuring the ability to:

  • mock responses based of OpenAPI spec
  • make requests to a HTTP server
  • validate the request and/or the response according to the provided OpenAPI Specification file

In essence it's an HTTP client with the ability to mock responses and validate requests.

The goal of this document is to provide you with some basic code examples to get you started and to cover some of the advanced scenarios.

Important

If you're a regular user and not a PRO, you might to want to use the User facing client which provides a better an higher lever API

Table of Contents

Installation

yarn add @stoplight/prism-http

Basic Usages

Note: the examples in this document use the following spec

openapi: 3.0.2
paths:
  /todos:
    get:
      parameters:
        - name: title
          in: query
          style: form
          schema:
            enum:
              - eat
              - drink
      responses:
        200:
          description: Get Todo Items
          content:
            'text/plain':
              example: Write great OpenAPI specs!

Mock All Responses

const Prism = require('@stoplight/prism-http');

// Create Prism instance and configure it as a mocker generating static examples
const prism = Prism.createInstance({
  mock: { dynamic: false },
  validate: { request: { query: true } },
});

// Make a "GET /todos" request
return prism.request(
  {
    method: 'get',
    url: {
      path: '/todos',
    },
    headers: {
      Accept: 'text/plain',
    },
  },
  operations
);

Output

{
  statusCode: 200,
  headers: { 'Content-type': 'text/plain' },
  body: 'Write great OpenAPI specs!'
}

Note: the request method returns a TaskEither monad. So in case you want to extract the result, you're going to need to use the pipe function.

return pipe(
  prism.request(
    {
      method: 'get',
      url: {
        path: '/todos',
      },
      headers: {
        Accept: 'text/plain',
      },
    },
    operations
  ),
  TE.fold(console.error, console.log)
)(); // returns a Promise

Mock Single Response

In the following example we will first instantiate Prism to make requests to an actual server.

Later we alter than behaviour by passing a config object to the request function.

const Prism = require('@stoplight/prism-http');

// Note that by default we don't want to mock responses
const prism = Prism.createInstance({ mock: { dynamic: false } });

// Make a "GET /todos" request
return prism.request(
  {
    method: 'get',
    url: {
      path: '/facts',
      baseUrl: 'https://cat-fact.herokuapp.com',
    },
  },
  {
    // We can override the default behaviour per request.
    mock: {
      dynamic: true,
    },
  },
  operations
);

Make Request To An Upstream Server

We don't want to mock a reqeust, we simply want to make the request, hit the actual server and get the response back.

const Prism = require('@stoplight/prism-http');

// Create Prism instance and configure it to make HTTP requests (mock: {dynamic: false})
const config = { mock: { dynamic: false } };
const prism = Prism.createInstance(config);

return prism.request({
  method: 'get',
  url: {
    path: '/facts',
    baseUrl: 'https://cat-fact.herokuapp.com',
  },
});

In response you'll get some... facts about cats. For example:

Cats aren’t the only animals that purr — squirrels, lemurs, elephants, and even gorillas purr too.

:)

Advanced Topics

Creating Prism Instance

In order to create and instance of HTTP Client (later referred to as prism for simplicity) use the createInstance function, like so:

const Prism = require('@stoplight/prism-http');
const config = { mock: { dynamic: false } };
const prism = Prism.createInstance(config /*, components */);

There are two (both optional) arguments you can supply createInstance with:

  • config (of IHttpConfig type)
  • components (of PrismHttpComponents type)

We will cover the config argument in next section and we'll leave components for some other time (overriding default components is the ultimate advanced stuff).

Config Object

Prism's config object (IHttpConfig) allows you to manipulate Prism's behaviour in many ways. For instance:

  • turn validation on and off
  • influence Prism's mocked response generation strategy

The actual interface looks like this (but rather than explain each property we're going to look at some examples)

export interface IHttpConfig extends IPrismConfig {
  mock: { dynamic: false } | IHttpOperationConfig;
  validateRequest: boolean;
  validateResponse: boolean;
  checkSecurity: boolean;
  errors: boolean;
}

Config Examples

When mocking a response generate static response

const config = {
  mock: {
    dynamic: false,
  },
};

Generating static responses means that if an OpenAPI operation's response has any examples defined the payload we construct will use those examples.

This contrasts "dynamic responses" which means generating responses from a json schema.

Return named example of a specified key

const config = {
  mock: {
    exampleKey: 'key',
  },
};

In OpenAPI Specification 3 one can construct such response that will have multiple examples mapped by keys. This configuration allows you to be very specific which example you want to choose.

Return 403 response of specified mime type

const config = {
  mock: {
    code: 403,
    mediaTypes: ['application/xml'],
  },
};

This will enforce a 403 response (given that such response is defined in your OpenAPI file).

Loading specs

The Http package does not have any pre-canned loader for the specification files. You need to feed it with an array of operations that can be used for the request/response cycle.

You can find an example by looking at the operations.ts file in the CLI package.

Making requests

To make a basic request you need to do the following

const request = {
  method: 'get',
  url: {
    path: '/path', // must be prefixed with slash
  },
};
const promise = prism.request(request, operations);

The request object has the following interface

export interface IHttpRequest {
  method: HttpMethod;
  url: IHttpUrl;
  headers?: IHttpNameValue;
  body?: unknown;
}

All of this is pretty standard except the url.baseUrl which we will describe in more details.

Server Validation

Consider a request

prism.request(
  {
    method: 'get',
    url: {
      path: '/facts', // must be prefixed with slash
      baseUrl: 'https://cat-fact.herokuapp.com',
    },
  },
  operations
);

Notice that baseUrl is defined.

This will instruct Prism to do one of the two:

  • if mocking is disabled ({ mock: {dynamic: false} })
    • it will use that baseUrl to make a request to the server (GET https://cat-fact.herokuapp.com/facts)
    • it will verify whether the provided baseUrl matches any of the servers defined in your OpenAPI and add an input warning to the .request return value if it is not valid
  • if mocking is enabled
    • it will verify whether the provided baseUrl matches any of the servers defined in your OpenAPI and return an error if it is not valid

Understanding response

The prism.request resolved (it's a Promise!) value consists of:

  • input - copy of the request object you provided
  • output - the HTTP response
  • validations
    • input - list of warnings/errors related to you http request object
    • output - list of warnings/errors related to you http response object

Validations are still subject of tests and experimentation therefore we will not cover them fully for the time being.

One example however is that for a given example

const Prism = require('@stoplight/prism-http');

// Create Prism instance and configure it to make http requests
const config = { mock: { dynamic: false } };
const prism = Prism.createInstance(config);
prism.request(
  {
    method: 'get',
    url: {
      path: '/facts',
      baseUrl: 'https://cat-fact.herokuapp.com',
    },
  },
  operations
);

You would get this in response

[
  {
    message: 'Route not resolved, no resource provided.',
    source: 'https://stoplight.io/prism/errors#NO_RESOURCE_PROVIDED_ERROR',
    code: 404,
    severity: 1
  }
]

Prism Decision Flow Diagram

The below diagram represents all logical decision we make to figure out the best HTTP response to the specific request.

Decision Flow Diagram