# Mir Client

[Mir](https://bitbucket.org/hlkagency/hlk-mir/src/master/) is a framework that provides both an API that can be accessed by front-end client applications and an admin dashboard for managing data associated with the particular API instance. APIs associated with Mir should be accessed using the [Mir client library](https://bitbucket.org/hlkagency/hlk-mir-client/src/master/).

The Mir client is a Javascript library designed to abstract away most of the API functionality making it easy for the front-end developer to access the data without having to worry about the specifics of the HTTP request.

### Using the client

First add the client to the project: `npm install --save mir-client`

The client can then be imported into the project. For example, in the following code snippet we will get data from an 'applicator' collection:

```javascript
import mir from 'mir-client'

var api_url = 'http://some-api.whatever.com'

// Create a main API Client
var api_client = mir(api_url)
var resource = api_client('resourceName')

function get_applicator_data() {
  return resource.get().send().then((result) => {
    return result
  })
}
```

This should return a response that has a structure like this:

```javascript
{
  config: {...},
  data: {...},
  headers: {...},
  request: {...},
  status: 200,
  statusText: "OK"
}
```

The `data` object within this request will have the relevant data from the API. This `data` object will have a structure like this:

```javascript
{
  _items: [...],
  _links: {...},
  _meta: {...}
}
```

The `_items` array will contain an array of the actual data objects. `_links` will probably never be used in front-end development.

The `_meta` object within `data` will contain information about the request. It will have a structure like this:

```javascript
{
  max_results: 25,
  page: 1,
  total: 2
}
```

### Client functions

The client can be used to perform any standard REST actions.

**GET**
```javascript
// the .get() function is used to make a GET request
resource.get().send().then((result) => {
  return result
}
```

**GET ONE**

```javascript
// the .getOne() function takes an id parameter
// it should be used to get one resource by its id
var existing_applicator_id = '1234'

resource.getOne(existing_applicator_id).send().then((result) => {
  return result
}
```

**POST**

```javascript
// the .post() function takes params of the targeted collection and the payload
// it should be used to make a POST request--i.e. to create a new resource
var new_applicator_object = {
  'business_name': 'Some Guy Inc.',
  'phone': '867-5309',
  'zip_code': '10001'
}

resource.post(new_applicator_object).send().then((result) => {
  return result
}
```

**PATCH**

```javascript
// the .patch() function takes params of the targeted collection and the payload
// it should be used to make a PATCH request--i.e. to update an existing resource
var update_this_id = '1234'
var applicator_update_object = {
  'business_name': 'Some Other Guy Inc.'
}

resource.patch(update_this_id, applicator_update_object).send().then((result) => {
  return result
})
```

**DELETE**
```javascript
// the .deleteOne() function takes params of the targeted collection and the id
// it should be used to make a DELETE request in order to delete one resource by its id
var delete_this_id = '1234'

resource.deleteOne(delete_this_id).send().then((result) => {
    return result
})
```

### Additional functions

Some of the REST functions have additional functions that can be chained to them. All functions include a `.send()` function. This function actually makes the request and returns a node.js promise. Every request must call `.send()` in order to actually make a request and return data. GET and GET ONE both include initial filtering functions. POST and PATCH, at this time, do not support additional filtering.

**GET**

`projection` -- takes a property and either true/false as parameters. Allows for specifying whether to return only certain values `.projection('name', true)` or to exclude certain values `.projection('name', false)`.<br/>
`sort` -- takes a property and either +/- as parameters. Allows for returning results sorting either ascending `.sort('name', '+')` or descending `.sort('name', '-')`.<br/>
`filter` -- takes a MongoDB query object that can be used to specify which objects should be returned in the result. For more information on this, refer to [How to Query MongoDB](mongo_queries.md).<br/>
`page` -- takes a number and returns that page of the specified request `.page(3)`.<br/>
`limit` -- takes a number and updates the `max_results` parameter for the request `.limit(50)`.<br/>
`next` -- returns the next page, will only work if an initial request has been made.<br/>
`previous` -- returns the previous page, will only work if an initial request has been made.<br/>
`first` -- returns the first page, will only work if an initial request has been made.<br/>
`last`-- returns the last page, will only work if an initial request has been made.<br/>
`send`-- sends the request.

Example:

```javascript
resource.get()
  .filter(
    {
      'resource_name': 'My Resource',
      'resource_date': {'$gt': 'Wed, 06 Jun 2018 14:52:37 GMT'}
    }
  )
  .sort('resource_date', '-')
  .send()
  .then((result) => {
    return result
  }
```

**GET ONE**

`projection` -- takes a property and either true/false as parameters. Allows for specifying whether to return only certain values `.projection('name', true)` or to exclude certain values `.projection('name', false)`.<br/>
`send`-- sends the request.

For more detail about how these functions interact with the API code, the [Eve documentation](http://python-eve.org/features.html) can be consulted.
