# Getting Started

Install Rivet using npm:

```
npm install --save-dev rivet
```

Or via yarn:

```
yarn add --dev rivet
```

Let's get started by creating a simple service API. First, create a file `route.js`

```javascript
module.exports = function (request, response) {
  const payload = {
    data: {
      userId: 1,
      id: 1,
      title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
      body: 'quia et suscipit suscipit recusandae consequuntur expedita et cum reprehenderit molestiae ut ut quas totam nostrum rerum est autem sunt rem eveniet architecto'
    }
  };

  response.status(200).json(payload);
};
```

Then, create a basic consumer contract file at `contracts/example.contract.js`

```javascript
module.exports = {
  title: 'Example',
  type: 'object',
  properties: {
    data: {
      type: 'object',
      properties: {
        userId: { type: 'integer' },
        id: { type: 'integer' },
        title: { type: 'string' },
        body: { type: 'string' }
      },
      required: ['userId', 'id', 'title', 'body'],
    }
  },
  required: ['data'],
};
```

## Writing Tests

### Consumer Test: Stubbing Data with a Contract

By using the contract to generate data for your contract tests, changes to the contract should expose any breaking-changes to the service API.

#### Install dependencies:

```
npm install nock axios jest --save-dev
```

#### Create a `consumer.test.js` file

```javascript
const { generateSync } = require('rivet');
const nock = require('nock');
const axios = require('axios');

describe('My Api', () => {
  it('satisfies the contract', (done) => {
    const stubbedData = generateSync('example.contract');

    nock('http://fakeser.ver')
    .get('/example')
    .reply(200, stubbedData);

    axios.get('http://fakeser.ver/example')
    .then((response) => {
      const payloadKeys = Object.keys(response.data);

      expect(payloadKeys)
      .toEqual(expect.arrayContaining([
        'userId',
        'id',
        'title',
        'body'
      ]));

      done();
    });
  });
});
```

### Service Test: Satisfying a Contract

Contracts can be used in any environment, given that they are JSON Schema files. The example here shows testing in a node environment, with jest, to validate that your api satisfies a consumer contract.

#### Install dependencies:

```
npm install jest jest-json-schema supertest express --save-dev
```

#### Create a `service.test.js` file

```javascript
const { matchers } = require('jest-json-schema');
const { load } = require('rivet');
const request = require('supertest');
const express = require('express');
const route = require('./route');

// add the jest-json-schema matchers to expect
expect.extend(matchers);

// setup the express app, with your new route
const app = express();
app.get('/example', route);

describe('My Api', () => {
  it('satisfies the contract', () => {
    // load the contract
    const schema = load('example.contract');

    request(app)
    .get('/example')
    .set('Accept', 'application/json')
    .expect(200)
    .then(response => {
      // Validate the response with the contract
      expect(response).toMatchSchema(schema);
    });
  });
});
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://rivet.itg.sh/getting-started.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
