## File: README.md

[][mocking_landing_page]

[![CircleCI][circle_ci_image]][circle_ci]
[![NPM Downloads][npm_image]][npm]
[][stoplight_forest]

# Prism Overview

Prism is a set of packages for API mocking and contract testing with **OpenAPI v2** (formerly known as Swagger) and **OpenAPI v3.x**.

Prism provides:

- **Mock Servers**: Life-like mock servers from any API specification document.
- **Validation Proxy**: Contract Testing for API consumers and developers.
- **Comprehensive API Specification Support**: OpenAPI v3.1, OpenAPI v3.0, OpenAPI v2.0 (formerly Swagger) and Postman Collections.

## Ways to Use Prism

### Hosted Prism

Stoplight provides hosted mock servers for convenience so that API consumers can experiment with an API without the need for backend code.

Use one of these options for instant, hosted mock servers:

- [Stoplight Platform](https://stoplight.io/?utm_source=github.com&utm_medium=referral&utm_campaign=github_repo_prism): Collaborative API Design Platform for designing, developing and documenting APIs with hosted mocking powered by Prism.
- [Stoplight Studio](https://stoplight.io/studio/?utm_source=github.com&utm_medium=referral&utm_campaign=github_repo_prism): Free visual OpenAPI designer that comes integrated with mocking powered by Prism.

Learn more in the [hosted Prism documentation](https://docs.stoplight.io/docs/platform/336b74db38c50-work-with-mock-servers).

### Self-hosted Prism

Prism is an open-source HTTP server run from the command-line. It provides mocking, request validation, and content negotiation. Use it standalone tool or in continuous integration.



## Installation and Usage

This information refers to Open Source Prism 3.x, which is the current version most likely you will use. If you're looking for the 2.x version, look at the [`2.x` branch][2.x]

### Install Self-hosted Prism

Prism requires

- NodeJS >= 18.20.1
- for NodeJS 18.x, [>= 18.16 is required](https://github.com/stoplightio/prism/issues/2305)

```bash
npm install @stoplight/prism-cli
```

For more installation options, see our [installation documentation](./docs/getting-started/01-installation.md).

### Mocking

Prism can help you create a fake "mock" based off an OpenAPI document, which helps people see how your API will work before you even have it built. Run it locally with the `prism mock` command to run your API on a HTTP server you can interact with.

```bash
prism mock https://raw.githack.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore-expanded.yaml
```

Learn more about [how the mock server works](docs/guides/01-mocking.md).

### Validation Proxy

Prism can help you check for discrepencies between your API implementation and the OpenAPI document that describes, letting you funnel HTTP traffic through it with the `prism proxy` command.

```bash
prism proxy examples/petstore.oas2.yaml https://petstore.swagger.io/v2
```

Learn more about [how the validation proxy works](docs/guides/03-validation-proxy.md).

## 📖 Documentation and Community

- [Documentation](https://docs.stoplight.io/docs/prism/674b27b261c3c-prism-overview)
  - [Getting Started](./docs/getting-started/01-installation.md)
  - [Guides](./docs/guides/01-mocking.md)
- [Community](https://github.com/stoplightio/prism/discussions)

### ❓ FAQs

**Cannot access mock server when using Docker?**

Prism uses localhost by default, which usually means 127.0.0.1. When using docker the mock server will
be unreachable outside of the container unless you run the mock command with `-h 0.0.0.0`.

**Why am I getting 404 errors when I include my basePath?**

OpenAPI v2.0 had a concept called "basePath", which was essentially part of the HTTP path the stuff
after host name and protocol, and before query string. Unlike the paths in your `paths` object, this
basePath was applied to every single URL, so Prism v2.x used to do the same. In OpenAPI v3.0 they
merged the basePath concept in with the server.url, and Prism v3 has done the same.

We treat OAS2 `host + basePath` the same as OAS3 `server.url`, so we do not require them to go in
the URL. If you have a base path of `api/v1` and your path is defined as `hello`, then a request to
`http://localhost:4010/hello` would work, but `http://localhost:4010/api/v1/hello` will fail. This
confuses some, but the other way was confusing to others. Check the default output of Prism CLI to
see what URLs you have available.

### 🚧 Roadmap

- [x] Content Negotiation
- [x] Security Validation
- [x] Validation Proxy
- [ ] [Recording/Learning Mode](https://roadmap.stoplight.io/c/324-learning-recording?utm_source=github&utm_medium=prism&utm_campaign=readme) (create OpenAPI from HTTP traffic)
- [ ] [Data Persistence](https://roadmap.stoplight.io/c/308-persisted-mock-data?utm_source=github&utm_medium=prism&utm_campaign=readme) (allow Prism act like a sandbox)

Submit your ideas for new functionality on the [Stoplight Roadmap](https://roadmap.stoplight.io/?utm_source=github&utm_medium=prism&utm_campaign=readme).

### 🏁 Help Others Utilize Prism

If you're using Prism for an interesting use case, [contact us](mailto:growth@stoplight.io) for a case study. We'll add it to a list here. Spread the goodness 🎉

### 👏 Contributing

If you are interested in contributing to Prism itself, check out our [contributing docs ⇗][contributing] and [code of conduct ⇗][code_of_conduct] to get started.

### 🎉 Thanks

Prism is built on top of lots of excellent packages, and here are a few we'd like to say a special thanks to.

- [ajv](https://www.npmjs.com/package/ajv)
- [faker](https://www.npmjs.com/package/@faker-js/faker)
- [fp-ts](https://www.npmjs.com/package/fp-ts)
- [gavel](https://www.npmjs.com/package/gavel)
- [json-schema-faker](https://www.npmjs.com/package/json-schema-faker)
- [lerna](https://www.npmjs.com/package/lerna)
- [micri](https://www.npmjs.com/package/micri)
- [openapi-sampler](https://www.npmjs.com/package/openapi-sampler)
- [yargs](https://www.npmjs.com/package/yargs)

Check these projects out!

### 🌲 Sponsor Prism by Planting a Tree

If you would like to thank us for creating Prism, we ask that you [**buy the world a tree**](https://ecologi.com/stoplightinc).

[code_of_conduct]: CODE_OF_CONDUCT.md
[contributing]: CONTRIBUTING.md
[download-release]: https://github.com/stoplightio/prism/releases/latest
[core]: https://www.npmjs.com/package/@stoplight/prism-core
[http]: https://www.npmjs.com/package/@stoplight/prism-http
[http-server]: https://www.npmjs.com/package/@stoplight/prism-http-server
[cli]: https://www.npmjs.com/package/@stoplight/prism-cli
[cli-docs]: ./docs/getting-started/03-cli.md
[2.x]: https://github.com/stoplightio/prism/tree/2.x
[http-docs]: packages/http/README.md
[mocking_landing_page]: https://stoplight.io/api-mocking?utm_source=github.com&utm_medium=referral&utm_campaign=github_repo_prism
[npm]: https://www.npmjs.com/package/@stoplight/prism-cli
[npm_image]: https://img.shields.io/npm/dw/@stoplight/prism-http?color=blue
[stoplight_forest]: https://ecologi.com/stoplightinc

---

## File: docs/guides/01-mocking.md

# HTTP Mocking

Prism's HTTP mock server simulates a real web API by providing endpoints and validation rules described in your API description document. This allows client developers to begin writing code for frontend services like web, mobile, or other backend applications, while API developers are still writing code. This can help find and solve problems early on, before the API is built, because changing all that code can be expensive.

- Does the API contain the information the client needs?
- Is that data in the format the client needs?
- Are the resources too "normalized" and data-centric (instead of being use-case centric) that the client has to make 3292375 calls to get all the data they need?
- Is there enough time left for feedback to be implemented?
- If the feedback spawns large enough work, will the client have time to implement this API once it's done?

You can avoid these problems by getting a free API to play with without spending a month building it all.

Catching problems early on while you're still just tweaking the API descriptions (maybe using [Stoplight Studio](https://stoplight.io/studio)), means you can avoid making costly changes to the production API, deprecating old things, or creating whole new global versions which add a huge workload to every single client.

Just like HTTP messages, there are two halves to mocking: requests and responses.

- [Response Generation](#response-generation)
- [Request Validation](#request-validation)

## Response Generation

Prism will try to return meaningful responses based on whatever information it has available, like response examples, and use various fallback mechanisms in case no examples were provided. This means any OpenAPI description document can be used with no extra work, but better documents provide better results.

The first thing to understand is that the Prism HTTP Server respects [Content Negotiation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation). If your API is a mixture of JSON, XML and form data, you can use `Accept`
and `Content-Type` just like with a real API, and it should work as expected, or fail if you request non-existent types.

### Prism Decision Engine

Prism responses are based on the following decision diagram.

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Response Examples

If a response has an example, it will be used for that response. If there are multiple examples, then they can be selected by name. In the following OpenAPI description, the operation has a 200 OK response and multiple examples:

```yaml
responses:
  '200':
    content:
      application/json:
        schema:
          '$ref': '#/components/schemas/Pet'
        examples:
          cat:
            summary: An example of a cat
            value:
              id: 2
              name: Fluffy
              photoUrls: []
          dog:
            summary: An example of a dog
            value:
              id: 1
              name: Spot
              photoUrls:
                - https://images.dog.ceo/breeds/kelpie/n02105412_893.jpg
```

Calling `curl http://127.0.0.1:4010/pets/123` on this will give:

```json
{
  "id": 2,
  "name": "Fluffy",
  "photoUrls": []
}
```

Calling the same URL with the `Prefer` header `example=dog` `http://127.0.0.1:4010/pets/123` will yield to:

```json
{
  "id": 1,
  "name": "Spot",
  "photoUrls": ["https://images.dog.ceo/breeds/kelpie/n02105412_893.jpg"]
}
```



> #### Remember to provide an expected response code
>
> It's always worth indicating the HTTP response code from which `example` should be taken. If Prism decides to change the response code due to validation or security violations, your `example` might be ignored.

### Static or Dynamic Generation

By default, Prism uses a **static generation strategy**, which is outlined below. You can enable the dynamic examples generation by using the `-d` flag in the command line.

```yaml
prism mock api.oas3.yaml # Static examples

prism mock -d api.oas3.yaml # Dynamic examples
```

If the HTTP server has been started in static mode, specific calls can be made in dynamic mode by specifying the `Prefer` header with the `dynamic` key set to `true`.

#### Static Response Generation

If the provided OpenAPI Schema Object has a response body example, it's used to provide a response.

If not, a response body will be created by looking through the whole `schema` object (following any `$ref`'s it finds along the way) to create a full fake response.

- If the property has a default value, then it will return the specified value.
- If the property has an `examples` value, then it will return the first element in the array.
- If the property has neither an example nor a default value and **is nullable**, it will return null.
- If the property has neither an example nor a default value and **isn't nullable**, but has a `format` specified, then it will return a meaningful static value according to the format.
- If the property has neither an example nor a default value, isn't nullable, and has no `format` specified, then it will return `'string'` in case of a string and `0` in case of a number.

For example, this is a schema component found in an OpenAPI description document:

```yaml
Pet:
  type: object
  properties:
    id:
      type: integer
      format: int64
    name:
      type: string
      example: doggie
    photoUrls:
      type: array
      items:
        type: string
```

When you call `curl http://127.0.0.1:4010/pets/123`, the operation references this component and a `doggie` is returned:

```json
{
  "id": 0,
  "name": "doggie",
  "photoUrls": ["string"]
}
```

Notice that `name` had an `example` with a value so Prism used it, but `photoUrls` didn't, so it just returned `"string"`.

Users also have the option to use the command-line flag `--ignoreExamples`. When present, and in static mode, the flag tells Prism to treat the spec as if it doesn't have any response examples defined. In this case, Prism continues to do what it already does in static mode when no response example are present, which is to return an example that has not been generated using json-schema-faker, but was created by Prism (it replicates the behavior of the situation just above where no response examples are given in the schema). However, when the `--ignoreExamples` flag is present, and in dynamic mode, the flag is essentially ignored, since in dynamic mode, examples are not consulted and json-schema-faker is used to generate a response based on the schema defined in the spec.

#### Dynamic Response Generation

Testing against the exact same piece of data over and over again isn't the best way to build a robust integration. What happens when a name is longer than you expected, or the value happens to be 0 instead of 6?

Dynamic mode solves this by generating a random value for all the properties according to their type, and other information like `format` or even by using the Faker library.

Read more about how to use Faker in [Dynamic Response with Faker](./11-dynamic-response-with-faker.md).

## Request Validation

Having a mock server that only gives responses would not be useful, which is why Prism imitates request validation too. An OpenAPI description document is full of validation rules like type, format, max length, etc. Prism can validate incoming messages and provide validation feedback if it receives invalid requests.

Read more about this in the [Prism Request Validation guide](./02-request-validation.md).

## Deprecating operations

If an operation is marked as `deprecated: true` then Prism adds `Deprecation: true` header to the response.

---

## File: docs/guides/02-request-validation.md

# Request Validation

Based on the API description document, Prism can take educated guesses at all sorts of validation rules for the request body, headers, query parameters, using keywords like `type`, `format`, `maxLength`, etc.

It can also fail with `401` if security information is missing, and do a bunch of other things the API description document says the real API will do. 

> Prism evaluates paths in the order they are listed in the API specification.

## Parameter Validation

Requests which expect a request body, query parameter, or a path parameter, will be validated.

For example, make a POST with a JSON body that's missing the required `name` parameter. 

```bash
curl -X POST -s -D "/dev/stderr" -H "content-type: application/json" -d '{"tag":"Stowford"}' http://127.0.0.1:4010/pets
```

In this case, Prism will:

- Look for a response with status code `422` on the operation you were trying to execute.
- If there's not a `422` defined, it will look for a response with status code `400` on the operation you were trying to execute.
- In case there's neither a `422` nor a `400` defined, Prism will create a `422` response code for you indicating the validation errors it found along the way. Such response will have a payload conforming to the [application/problem+json][rfc7807] specification.

Since the operation hasn't any error response defined, Prism will generate a 422 response:

```
HTTP/1.1 422 Unprocessable Entity
content-type: application/problem+json
content-length: 380
Date: Fri, 05 Jul 2019 07:56:18 GMT
Connection: keep-alive

{
   "type" : "https://stoplight.io/prism/errors#UNPROCESSABLE_ENTITY",
   "title" : "Invalid request.",
   "detail" : "Your request is not valid and no HTTP validation response was found in the spec, so Prism is generating this error for you.",
   "status" : 422,
   "validation" : [
      {
         "message" : "should have required property 'name'",
         "severity" : "Error",
         "code" : "required",
         "location" : [
            "body"
         ]
      }
   ]
}
```

This error shows effectively that the request is missing a required property `name` from the HTTP request body.

Pairing a GET with a request body is another example of a `422` response you may receive. 

## Server Validation

OpenAPI allows the entire API, or certain operations, to be associated with specific servers.

To make sure the server URL you plan to use is a valid server for the API, or for the particular operation you are attempting, provide it as a `__server` query parameter.

Take this minimalist OpenAPI example:

```yaml
openapi: 3.0.2
paths:
  '/pet':
    get:
      responses:
        '200':
          content:
            '*/*':
              schema:
                type: string
                example: hello world
servers:
  - url: https://stoplight.io/api
    name: Production
  - url: https://stag.stoplight.io/api
    name: Staging
```

You can make a request enforcing server validation by providing the `__server` query string parameter:

```bash
curl http://localhost:4010/pet?__server=https://stoplight.io/api
hello world
```

On the other hand, putting a server which isn't defined in the specification:

```bash
curl http://localhost:4010/pet?__server=https://nonsense.com/api
```

Will give you the following error:

```json
{
  "type": "https://stoplight.io/prism/errors#NO_SERVER_MATCHED_ERROR",
  "title": "Route not resolved, no server matched.",
  "status": 404,
  "detail": "The server url http://nonsense.com/api hasn't been matched with any of the provided servers"
}
```

[petstore-oas2]: ../../examples/petstore.oas2.yaml
[rfc7807]: https://www.tools.ietf.org/html/rfc7807

---

## File: docs/guides/03-validation-proxy.md

# Validation Proxy

Unlike mocking, the validation proxy expects there to be a real API running somewhere. This could be a localhost environment, docker container, hosted sandbox environment, or a production environment.

The proxy feature will help you identify discrepancies between the OpenAPI document and any other server you designate as the target. This can help frontend developers integrating with your API, or other backend developers, who might want to channel their requests through Prism to see if they're making valid requests. The proxy can also be enabled in staging or any other pre-production environment, like a dress rehearsal before the opening night of a play.

## Use Cases

### Assisting API Consumer Integration

In the [design-first workflow](https://blog.stoplight.io/api-first-api-design-first-or-code-first-which-should-you-choose), mocking gives your team something to use before the API exists. Then, when enough feedback has come in and the API developers have decided to start coding the API, the hope is that the real API matches the mock API. If it matches, the existing development work done by the API consumers during the feedback stage means that integrating the real API should involve little to no work. Sadly, subtle differences often go unnoticed, with properties changing slightly, or being removed completely.

API consumers can funnel their development traffic through Prism running as proxy, and then relay that traffic to the API-in-progress. It reports any mistakes it notices along the way, either with the requests you're sending or the responses coming back from the server.

In this use case, the OpenAPI documents are provided by the API team, distributed to the API consumers, and the proxy server points to the development environment. Also, enable `--errors` so Prism alerts you if a mismatch is noticed.

```bash
prism proxy reference/backend/openapi.yaml http://localhost:3000 --errors
```

> The proxy URL must begin with the protocol (`http`, `https`).

### End-to-End Contract Testing

Before the design-first workflow, folks would often slap together their own API descriptions, often by hand, and often just eyeball it for correctness. Various tools came and went for trying to test the correctness of their API description documents, but they were often awkward flaky test-suites that people ended just turning off. Adding contract testing to existing test-suites is now easy with Prism.

Teams with existing end-to-end test suites can drop Prism into this testing environment, and change some environment variables (or service catalog) to point to Prism Proxy. Each time API A talks to API B, or B to C, it will be going via C, so if any of the APIs make an invalid request the whole test suite can fail.

```bash
prism proxy reference/api-a/openapi.yaml api-a-test.example.com --errors -p 5000
prism proxy reference/api-b/openapi.yaml api-b-test.example.com --errors -p 5001
prism proxy reference/api-c/openapi.yaml api-c-test.example.com --errors -p 5002
```

This adds contract testing to an existing test suite, regardless of the language your APIs are written in, without any changes required to the codebases.

### Unimplemented Operations will be Mocked

In case the upstream server responds with the `501` status code, Prism will try to mock the call using the provided OpenAPI document.

### Live Contract Testing

Now you can use Prism to test traffic against the API description. This could be done in development, but it could also be placed in staging, QA, or some sort of pre-production environment. Probably keep it out of production, because even though Prism is quick like a fox, introducing _anything_ to the critical path of your API is probably not what you want.

### Deprecating operations

If an operation is marked as `deprecated: true`, Prism adds `Deprecation: true` header to the response if the response from remote server doesn't already contains that header.



> Future versions of Prism will include ways to sniff existing traffic, without requests being made directly to it, such as sniffing NGINX logs, or piping other forms of traffic through. [Get in touch with ideas](https://github.com/stoplightio/prism/issues/955).

---

## File: docs/guides/04-callbacks.md

# Mocking Callbacks with Prism

Callback in OpenPI 3.x defines an outgoing, asynchronous request that your service will make to some other service. Typical real-life example is a code repository. You can subscribe to certain events on a repo (like commit or tag) and your API will start receiving notifications for those events. Another example is one-time notifications. You can subscribe to a `invoice paid` event and a callback will be invoked when such payment is processed.

##### Sources:

- [Callback Docs](https://swagger.io/docs/specification/callbacks/)
- [Callback Object Specification](https://spec.openapis.org/oas/v3.0.2#callbackObject)

## Callback Example

This example shows how Prism mocks callbacks. There are two services defined: `payment-service` and `client-service`. `payment-service` exposes a subscribe-to-invoice-events method. Client service defines a notification reception endpoint. The goal is to programmatically subscribe to events about certain invoice.

### Environment setup

Start `payment-service` exposing `/subscribe` callback.

```bash
prism mock -p 4010 examples/callbacks/payment-service.oas3.yaml
```

Start `client-service` exposing `/notify` operation used for receiving callback requests.

```bash
prism mock -p 4011 examples/callbacks/client-service.oas3.yaml
```

### Run

Subscribe to callback

```bash
curl -v -H'Content-type: application/json' -d'{ "url": "http://localhost:4011/notify", "token": "ssecurre" }' http://127.0.0.1:4010/invoices/123/subscribe
```

Now, the console for `payment-service` should contain:

```
[HTTP SERVER] post /invoices/123/subscribe ℹ  info      Request received
    [NEGOTIATOR] ℹ  info      Request contains an accept header: */*
    [VALIDATOR] ✔  success   The request passed the validation rules. Looking for the best response
    [NEGOTIATOR] ✔  success   Found a compatible content for */*
    [NEGOTIATOR] ✔  success   Responding with the requested status code 202
    [CALLBACK] ℹ  info      actions: Making request to http://localhost:4011/notify?token=ssecurre...
    [CALLBACK] ℹ  info      actions: Request finished
```

The console of `client-service`:

```
[HTTP SERVER] post /notify ℹ  info      Request received
    [NEGOTIATOR] ℹ  info      Request contains an accept header: */*
    [VALIDATOR] ✔  success   The request passed the validation rules. Looking for the best response
    [NEGOTIATOR] ✔  success   Found a compatible content for */*
    [NEGOTIATOR] ✔  success   Responding with the requested status code 200
```

After subscribing via `/subscribe`, Prism successfully invoked `/notify` callback with mocked payload.

## Limitations

- no support for `servers` and `security` definitions inside callback operation
- no support for `$url` and `$request.path.*` runtime expressions

---

## File: docs/guides/05-cors.md

# CORS

By default, Prism will handle all the [preflight requests](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request) responding with a `204` and with headers that will allow all the methods and all the origins.

This is done automatically, even when your OpenAPI description doesn't include CORS response headers. A request to `OPTIONS /api/todo` will receive a `204` as a response even though your description document doesn't specify the `OPTIONS` verb for that endpoint, **and** even if your description document **doesn't** have an `/api/todo` path at all. However, if your OpenAPI description includes CORS headers, Prism won't override them, and you must ensure they enable requests from a browser on your own.

In case your OpenAPI Document specifies an `OPTIONS` handler (returning a custom status code or different headers) it will still be called when the subsequent `OPTIONS` request will be made. This is because Prism is able to differentiate between a preflight request and a regular `OPTIONS` request.

You can disable the default CORS handler with a command line flag (`prism mock document.yml --cors=false`). In that case, you are in complete control of the response for all the preflight request, and you can decide which header you want to return.

---

## File: docs/guides/06-errors.md

# Errors

All the errors that Prism returns conform to [RFC7807](https://tools.ietf.org/html/rfc7807) - Problem Details for HTTP APIs, which means you'll always get a **JSON object** with the following properties:

- `type` (string)
- `title` (string)
- `status` (number)
- `detail` (string)

This document enumerates all the possible errors returned by Prism and provides some further information on how to solve them.

## Routing Errors

This class of errors is returned when Prism is trying to identify the right resource to use to respond to the provided HTTP Request.

### NO_BASE_URL_ERROR

**Message: Attempted to make a request to a server but neither baseUrl param were provided nor servers were defined in the spec**

**Returned Status Code: `400`**

**Explanation:** This error occurs when Prism is being used as a proxy and the current document is missing at least a server in the dedicated array (both globally and locally). The proxy functionality is currently disabled in Prism, so this error should never happen.

---

### NO_RESOURCE_PROVIDED_ERROR

**Message: Route not resolved, no resource provided**

**Returned Status Code: `404`**

**Explanation:** This error occurs when the current document doesn't have any endpoint.

##### Example

```yaml
openapi: 3.0.1
paths:
```

`curl -X POST http://localhost:4010/pets`

---

### NO_PATH_MATCHED_ERROR

**Message: Route not resolved, no path matched**

**Returned Status Code: `404`**

**Explanation:** This error occurs when the current document doesn't have any endpoint matching the requested URL.

##### Example

```yaml
openapi: 3.0.1
paths:
  /pets:
    get:
      responses:
        200:
```

`curl -X POST http://localhost:4010/hello`

---

### NO_SERVER_MATCHED_ERROR

**Message: Route not resolved, no server matched**

**Returned Status Code: `404`**

**Explanation:** This error occurs when the server validation is enabled, and the current request **hasn't** sent the current server or the provided one isn't among the defined in the relative array in the file.

##### Example

```yaml
openapi: 3.0.0
paths:
  '/pet':
    get:
      responses:
        '200': {}
servers:
  - url: '{schema}://{host}/{basePath}'
    variables:
      schema:
        default: http
        enum:
          - http
          - https
      host:
        default: stoplight.io
        enum:
          - stoplight.io
          - dev.stoplight.io
      basePath:
        default: api
```

`curl "http://localhost:4010/pet?__server=http%3A%2F%2Finvalidserver.com"`

---

### NO_METHOD_MATCHED_ERROR

**Message: Route resolved, but no path matched**

**Returned Status Code: `405`**

**Explanation:** This error occurs when the current document has an endpoint with the requested URL, but the specified Verb isn't listed.

##### Example

```yaml
openapi: 3.0.1
paths:
  /pets:
    get:
      responses:
        200:
```

`curl -X POST http://localhost:4010/pets`

---

### NO_SERVER_CONFIGURATION_PROVIDED_ERROR

**Message: Route not resolved, no server configuration provided**

**Returned Status Code: `404`**

**Explanation:** This error occurs when a base URL has been provided in the current request (enabling the server validation feature) but the current document doesn't have any `servers` field/entry.

## Validation Errors

This class of errors is returned when Prism is validating the request/response against the provided OpenAPI file.

### UNPROCESSABLE_ENTITY

**Message: Invalid request**

**Returned Status Code: `422`**

**Explanation:** This error occurs when the current request hasn't passed the validation rules specified in the current OpenAPI file _and_ the current resource is missing an error message (`422`, `400`, `default`). Note that this is an error _generated_ by Prism.

The `detail` field contains further information on the error (whether it's on the body, the headers or the query string).

---

### NOT_ACCEPTABLE

**Message: The server can't produce a representation for your accept header**

**Returned Status Code: `406`**

**Explanation:** This error occurs when the current request has asked the response in a format that the current document isn't able to produce.

##### Example

```yaml
openapi: 3.0.2
paths:
  /todos:
    get:
      responses:
        200:
          examples:
            text/plain: hello
```

```
curl http://localhost:4010/todos -H "accept: application/json"`
```

---

### NOT_FOUND

**Message: The server can't find the requested content**

**Returned Status Code: `404`**

**Explanation:** This error occurs when the current request is asking for a specific status code that the document isn't listing or it's asking for a specific example that doesn't exist in the current document.

### VIOLATIONS

**Message #1: Request/Response not valid**

**Returned Status Code: `500`**

**Explanation:** This error occurs when you're run Prism with the `--errors` flag and the request or the response has at least one violation marked as an error.

**Message #2: response.body Request body must match exactly one schema in oneOf**

**Returned Status Code: N/A**

**Explanation:** This error can occur if the current document contains a [discriminator](https://spec.openapis.org/oas/v3.0.1.html#discriminator-object). Prism does not support discriminators. 

---

## Security Errors

This class of errors is returned when the current request isn't satisfying the security requirements specified in the current resource

### UNAUTHORIZED

**Message: Invalid security scheme used**

**Returned Status Code: `401`**

**Explanation:** This error occurs when the security scheme for the current resource doesn't match the one that the one that the request being processed has provided.

---

## Negotiation Errors

This class of errors is returned when anything goes wrong between your **valid** request and returning a suitable response

### NO_COMPLEX_OBJECT_TEXT

**Message: Can't serialise complex objects as text**

**Returned Status Code: `500`**

**Explanation:** This error occurs when the current request accepts the `text/*` as the response content type and Prism decided to respond with that, but the schema associated with the selected response of the operation generated a non-primitive payload and Prism can't serialise it.

##### Example

```yaml
openapi: '3.0.1'
paths:
  /:
    get:
      responses:
        200:
          content:
            text/plain:
              schema:
                type: object
                properties:
                  name:
                    type: string
                    example: Clark
                  surname:
                    type: string
                    example: Kent
```

`curl -X POST http://localhost:4010/ -A 'Accept: text/plain'`

### NO_RESPONSE_DEFINED

**Message: No response defined for the selected operation**

**Returned Status Code: `500`**

**Explanation:** This error occurs when the current request has matched a corresponding HTTP Operation and has passed all the validations, but there's no response that could be returned.

### INVALID_CONTENT_TYPE

**Message: Supported content types: _list_**

**Returned Status Code: `415`**

**Explanation:** This error occurs when the current request specifies a `Content-Type` that isn't supported by corresponding HTTP Operation. In the case there is no request body or `Content-Length` is 0, the `Content-Type` header is ignored.


### SCHEMA_TOO_COMPLEX

**Message: Unable to generate [body|header] for response. The schema is too complex to generate.**

**Returned Status Code: `500`**

**Explanation:** This error occurs when part of the response can't be generated using JSON Schema Sampler. JSON Schema Sampler has been configured to use a limit of 2500 "ticks". A "tick" is loosely defined as any instance of a JSON Schema schema or subschema. This includes a/an single:
* Property
* Object
* Array item (each in an array between `minItems` and `maxItems`, defaulting to 1)
* Combiner item (members of `allOf`, `oneOf`, `anyOf`)
 
...all recursively, unless a `$ref` has already been visited (in which case, the subschema is skipped). As a workaround, consider using [dynamic response mocking](./11-dynamic-response-with-faker.md).

## Unknown Error

In case you get an `UNKNOWN` error, it likely means this particular edge case isn't handled. If you encounter one of these, open an [issue](https://github.com/stoplightio/prism/issues/new?labels=bug&template=bug_report.md).

---

## File: docs/guides/07-http-client.md

# Prism Client

Prism includes a HTTP Client that you can use to request data to both a real server or a mocked document. The client is modeled after Axios so it may feel familiar.

## Create Client from File

Use the `getHttpOperationsFromSpec` method defined in the `@stoplight/prism-cli` package to create the required operations array from an OpenAPI spec:

```ts
const { getHttpOperationsFromSpec } = require('@stoplight/prism-cli/dist/operations');
const { createClientFromOperations } = require('@stoplight/prism-http/dist/client');
const { URL } = require('url');

const operations = await getHttpOperationsFromSpec('examples/petstore.oas2.yaml');
const client = createClientFromOperations(operations, {
  mock: { dynamic: false },
  validateRequest: true,
  validateResponse: true,
  checkSecurity: false,
  errors: true,
  upstream: new URL('https://api.example.com'),
  upstreamProxy: undefined,
  isProxy: true,
});
```

The `getHttpOperationsFromSpec` method also receives the spec as a string:

```ts
const descriptionDoc = `
openapi: 3.0.2
paths:
  /hello:
    get:
      responses:
        200:
`;

const operations = await getHttpOperationsFromSpec(descriptionDoc);

...
```

## Create Client from Manual HTTP Operations

```ts
const { createClientFromOperations } = require('@stoplight/prism-http/dist/client');
const { URL } = require('url');

const client = createClientFromOperations(
  [
    {
      method: 'get',
      path: '/hello',
      id: 'n1',
      responses: [{ code: '200' }],
    },
  ],
  {
    mock: { dynamic: false },
    validateRequest: true,
    validateResponse: true,
    checkSecurity: false,
    errors: true,
    upstream: new URL('https://api.example.com'),
    upstreamProxy: undefined,
    isProxy: true,
  }
);
```

---

## Example usages

Once you've got a client instance:

### Request using the generic method:

```ts
client.request('https://google.it', { method: 'get' }).then(console.log);
```

The response object has all the information you need, including the used configuration object.

### Override the configuration object on the request level

```ts
const config = { validateResponse: false };
client.request('https://google.it', { method: 'get' }, config).then(console.log);
```

This disables response validation _only for the current request_

You can do the same thing using the shortcut methods

```ts
client.get('https://google.it', { mock: { dynamic: false } }).then(console.log);
```

For the shortcut methods (since the only mandatory option is intrinsic in the function name) the option parameter can be omitted

```ts
client.get('https://google.it', { validateRequest: false }).then(console.log);
```

You can also use relative links when doing requests. In such case you won't be able to use the proxy and the server validation will be disabled:

```ts
client.get('/users/10', { validateRequest: false }).then(console.log);
```

…or you can also set the base path in the options object:

```ts
client.get('/users/10', { baseUrl: 'https://api.stoplight.io/' }).then(console.log);
```

### Set mocking options

```ts
client.request('https://google.it', { method: 'get' }, { mock: { dynamic: true } }).then(console.log);
client
  .request('https://google.it', { method: 'get' }, { isProxy: true, upstream: new URL('https://api.example.com') })
  .then(console.log);
```

---

## File: docs/guides/08-multiple-documents.md

# Serving Multiple OpenAPI Documents

A single Prism instance serves one OpenAPI document, but serving multiple documents is possible by running multiple Prism instances on different documents, then serving their content using a reverse Proxy. 

You can use any HTTP proxy along with a process management tool to achieve this. The following example explains how to serve multiple OpenAPI documents using [Docker Compose](https://docs.docker.com/compose/).

## Preparing configuration files

Depending on your needs, you might have a `docker-compose.yaml` file like this:

```yaml
version: '3'
services:
  proxy:
    image: caddy
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
    ports:
      - '8080:80'
    depends_on:
      - prism_1
      - prism_2
  prism_1:
    image: stoplight/prism:4
    command: >
      mock -p 4010 --host 0.0.0.0
      https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v2.0/yaml/petstore.yaml
  prism_2:
    image: stoplight/prism:4
    command: >
      mock -p 4010 --host 0.0.0.0
      https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml
```

And the corresponding `Caddyfile` file:

```
http://localhost

route /app_1/* {
	uri strip_prefix /app_1
	reverse_proxy prism_1:4010
}

route /app_2/* {
	uri strip_prefix /app_2
	reverse_proxy prism_2:4010
}
```

This configuration will allow access to the first Prism instance on `localhost:8080/app_1` and the second instance on `localhost:8080/app_2` endpoint.
Also, the provided `Caddyfile` only serves illustrative purposes and hence shouldn't be considered complete nor production-ready.

## Running the cluster

First, place the aforementioned files under the same directory - here `prism-multi-example`.

```
prism-multi-example
├── docker-compose.yaml
└── Caddyfile
```

With the files in place, you can run (from under `prism-multi-example/`): `docker-compose up`.
After a second, you should be set up with two Prism instances serving different OAS documents.

## Testing the cluster

If you used `Caddyfile` configuration provided in this document, you should now have two endpoints available:

1. `http://localhost:8080/app_1`
2. `http://localhost:8080/app_2`

You can now try these out by issuing:

```bash
curl http://localhost:8080/app_1/pets
curl http://localhost:8080/app_2/pets
```

At this point, the responses should be given back without issues.

## Adding more documents

You can extend the cluster by adding more nodes to `docker-compose.yaml`.
Under `services`, you can add:

```yaml
prism_3:
  image: stoplight/prism:4
  command: >
    mock -p 4010 --host 0.0.0.0
    https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml
```

To make the new node accessible from the proxy, please also adjust `Caddyfile`:

```
route /app_3/* {
	uri strip_prefix /app_3
	reverse_proxy prism_3:4010
}

```

---

## File: docs/guides/09-postman-collection.md

# Postman Collections Support

Prism offers a _limited_ support for Postman Collection. The basic workflow of using Prism (both from the CLI and deployed in a Docker container) are fundamentally the same:

```bash
prism mock https://raw.githubusercontent.com/postmanlabs/postman-collection/develop/examples/collection-v2.json

info      GET        http://127.0.0.1:4010/status/200
info      POST       http://127.0.0.1:4010/post
info      PUT        http://127.0.0.1:4010/status/201
info      GET        http://127.0.0.1:4010/post
info      GET        http://127.0.0.1:4010/status/400/
info      GET        http://127.0.0.1:4010/path/to/document
start     Prism is listening on http://127.0.0.1:4010
```

…and then use the trusty curl to try out the server:

```bash
curl -s -D "/dev/stderr" http://127.0.0.1:4010/status/200

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: *
Content-type: application/json
authorization: Hawk id="dh37fgj492je", ts="1448549987", nonce="eOJZCd", mac="O2TFlvAlMvKVSKOzc6XkfU6+5285k5p3m5dAjxumo2k="
set-cookie: null
Content-Length: 15
Date: Mon, 09 Mar 2020 19:19:31 GMT
Connection: keep-alive

"response body"%
```

For a complete CLI overview, please see the [CLI page](../getting-started/03-cli.md)

## Known limitations

There are some known limitations that it's important to keep in mind:

### Authentication

Postman supports a few authentication schemes that OpenAPI doesn't, such as Hawk and AWS. In this case, Prism will do a simplified version of security validation and verify that you've got the right headers populated.

### Events

Events are linked to the Postman hosted platform, so Prism will skip this section entirely.

For this reason, if some event handlers have scripts that modify a local variable used in a request/response pair, Prism won't be aware of these changes. Global variables are not supported by Prism.

### JSON Schema Generation

OpenAPI 2 and 3 are schema driven, while Postman Collections are examples driven.

Essentially, while in OpenAPI 2/3 you can either define an example request/response body OR define a JSON Schema to describe how the payload will look like, in a Postman Collections you can only define examples.

Prism will _try_ to infer a JSON Schema from an example, and use such one to perform request/response validation as well as examples generation in case the it's running in `dynamic` mode.

Infer a JSON Schema from a payload is an operation usually complicated and there's no way a perfect result will be achieved. Keep in mind you might get legitimate validation errors.

To give an example, this JSON object:

```json
{
  "name": "Bugatti Veyron",
  "type": "Sport Car",
  "speed": 3000
}
```

will likely generate this schema:

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "type": {
      "type": "string"
    },
    "speed": {
      "type": "number"
    }
  }
}
```

Although the result seems good:

- There is no way to understand whether all or some properties are required or not, so they'll all be marked as optional.
- There is no way to understand whether a type is indeed an `enum` instead of a regular `string`. In this specific example, maybe the author's intention is that type is either `Sport Car` or `SUV`
- There is no way to understand whether a type can be something stricter; for example, maybe the author's intention was to mark the `speed` property as `integer` instead of `number`.

### Operations Merging

Postman Collections allows to define the same response multiple times, as long they differ for the returned response type, payload, examples. Prism will try to merge all these definitions in a single operation and then selecting the appropriate example based on its internal negotiator.