<commit_before># Rails Ranger
### Exploring the routes and paths of Rails APIs
> This library development is in an early stage and the API is unstable

#### [Github Repository](https://github.com/victor-am/rails-ranger) | [Documentation](https://victor-am.github.io/rails-ranger)

[![npm version](https://badge.fury.io/js/rails-ranger.svg)](https://badge.fury.io/js/rails-ranger)
[![Travis build status](http://img.shields.io/travis/victor-am/rails-ranger.svg?style=flat)](https://travis-ci.org/victor-am/rails-ranger)
[![Test Coverage](https://codeclimate.com/github/victor-am/rails-ranger/badges/coverage.svg)](https://codeclimate.com/github/victor-am/rails-ranger)
[![Dependency Status](https://david-dm.org/victor-am/rails-ranger.svg)](https://david-dm.org/victor-am/rails-ranger)
[![devDependency Status](https://david-dm.org/victor-am/rails-ranger/dev-status.svg)](https://david-dm.org/victor-am/rails-ranger#info=devDependencies)
[![Stories in Ready](https://badge.waffle.io/victor-am/rails-ranger.png?label=ready&title=Ready)](https://waffle.io/victor-am/rails-ranger?utm_source=badge)

Rails Ranger is a thin layer on top of [Axios](https://github.com/mzabriskie/axios), which gives you an opinionated interface to query APIs built with Ruby on Rails.

## Main features
- URL building following Ruby on Rails routes conventions
- Automatic transformation of camelCase into snake_case and back to camelCase when exchanging data between the front-end and the API

## Installation
```bash
npm install --save rails-ranger
```

**or**

```bash
yarn add rails-ranger
```
<br>

## How does it work?

The following example illustrates a simple usage of the library:

```javascript
// api-client.js
import RailsRanger from 'rails-ranger'

const config = {
  axios: { baseURL: 'http://api.myapp.com' }
}

export default new RailsRanger(config)
```

```javascript
// some-front-end-component.js
import api from 'api-client'

api.list('users').then((response) => {
  const users = response.data
})
```

The `list` function makes a request to the **index** path of the **users** resource, following Rails routing conventions. This means a `GET` request to the `/users` path.

Also we converted the *snake_cased* JSON generated by Ruby on Rails automaticaly to *camelCase*, as preferred in Javascript.

> **Observation:** you can use `api.index('users')` as well. The `list` function is just an alias for it.
<br>

### A slightly more advanced example:

```javascript
api.show('users', { id: 1, someParameter: false })
// => GET request to /users/1?some_parameter=false
```
<br>

### Build your own client object
You can build your own client object to centralize the API routes used by your front-end app.

This is indeed **highly recommended** for non-trivial applications, to avoid duplication, get better control of the API client interface and make your life easier in the event of you wanting to remove/replace this dependency from your project.

Below is an example of such implementation:

```javascript
// api-client.js
import RailsRanger from 'rails-ranger'

const client = new RailsRanger

export default {
  client,
  
  users: {
    list(params) {
      return this.client.list('users', params)
    }
  }

  blogPosts: {
    list(params) {
      return this.client.list('blogPosts', params)
    }
  }
}
```

```javascript
// some-front-end-component.js
import api from 'api-client'

api.users.list({ limit: 3 }).then((response) => {
  const users = response.data
})
```
<br>

## Options
As the first argument when creating a new instance of Rails Ranger you can pass an object of options to customize the behavior of the client.

### dataTransform
**default: true**

By default RailsRanger will convert camelCased keys in your jsons to snake_case when sending a request to Rails, and will convert the Rails response back from snake_case to camelCase for better usage within your javascript code.

You can disable this behavior by setting `dataTransform` to false:

```javascript
const api = new RailsRanger({ dataTransform: false })
```

---
### axios
**default: {}**

Any object passed to the `axios` option will be handled to **Axios**.
Here an example using the `baseUrl` configuration of Axios:

```javascript
const api = new RailsRanger({ axios: { baseUrl: 'http://myapp.com/api/v1' } })

api.list('users')
// => GET request to http://myapp.com/api/users
```

#### See more configuration options in the [Axios documentation](https://github.com/mzabriskie/axios#request-config)
<br>

## Use Rails Ranger just for path building
You don't need to use Rails Ranger as an ajax client if you don't want to. It can also be used just to generate the resource routes and then make the request with another tool. The following is an example of this usage:

```javascript
import { RouteBuilder } from RailsRanger
const routes = new RouteBuilder

routes.create('users', { name: 'John' })
// => { path: '/users', params: { name: 'John' }, method: 'post' }

routes.show('users', { id: 1, hidePassword: true })
// => { path: '/users/1?hide_password=true', params: {}, method: 'get' }

routes.get('/:api/documentation', { api: 'v1', page: 3 })
// => { path: 'v1/documentation?page=3', params: {}, method: 'get' }
```
<br>

## Available actions

### List/Index
```javascript
api.list('users', { limit: 3 })
// => GET request to /users?limit=3

api.index('users', { limit: 3 })
// => GET request to /users?limit=3
```

### Show
```javascript
api.show('users', { id: 1 })
// => GET request to /users/1
```

### New
```javascript
api.new('users')
// => GET request to /users/new
```

### Create<commit_msg>Add '.resource' function doc to README.md<commit_after># Rails Ranger
### Exploring the routes and paths of Rails APIs
> This library development is in an early stage and the API is unstable

#### [Github Repository](https://github.com/victor-am/rails-ranger) | [Documentation](https://victor-am.github.io/rails-ranger)

[![npm version](https://badge.fury.io/js/rails-ranger.svg)](https://badge.fury.io/js/rails-ranger)
[![Travis build status](http://img.shields.io/travis/victor-am/rails-ranger.svg?style=flat)](https://travis-ci.org/victor-am/rails-ranger)
[![Test Coverage](https://codeclimate.com/github/victor-am/rails-ranger/badges/coverage.svg)](https://codeclimate.com/github/victor-am/rails-ranger)
[![Dependency Status](https://david-dm.org/victor-am/rails-ranger.svg)](https://david-dm.org/victor-am/rails-ranger)
[![devDependency Status](https://david-dm.org/victor-am/rails-ranger/dev-status.svg)](https://david-dm.org/victor-am/rails-ranger#info=devDependencies)
[![Stories in Ready](https://badge.waffle.io/victor-am/rails-ranger.png?label=ready&title=Ready)](https://waffle.io/victor-am/rails-ranger?utm_source=badge)

Rails Ranger is a thin layer on top of [Axios](https://github.com/mzabriskie/axios), which gives you an opinionated interface to query APIs built with Ruby on Rails.

## Main features
- URL building following Ruby on Rails routes conventions
- Automatic transformation of camelCase into snake_case and back to camelCase when exchanging data between the front-end and the API

## Installation
```bash
npm install --save rails-ranger
```

**or**

```bash
yarn add rails-ranger
```
<br>

## How does it work?

The following example illustrates a simple usage of the library:

```javascript
// api-client.js
import RailsRanger from 'rails-ranger'

const config = {
  axios: { baseURL: 'http://api.myapp.com' }
}

export default new RailsRanger(config)
```

```javascript
// some-front-end-component.js
import api from 'api-client'

api.list('users').then((response) => {
  const users = response.data
})
```

The `list` function makes a request to the **index** path of the **users** resource, following Rails routing conventions. This means a `GET` request to the `/users` path.

Also we converted the *snake_cased* JSON generated by Ruby on Rails automaticaly to *camelCase*, as preferred in Javascript.

> **Observation:** you can use `api.index('users')` as well. The `list` function is just an alias for it.
<br>

### A slightly more advanced example:

```javascript
api.resource(users, 1).list('blogPosts', { someParameter: false })
// => GET request to /users/1/blog_posts?some_parameter=false
```
<br>

### Build your own client object
You can build your own client object to centralize the API routes used by your front-end app.

This is indeed **highly recommended** for non-trivial applications, to avoid duplication, get better control of the API client interface and make your life easier in the event of you wanting to remove/replace this dependency from your project.

Below is an example of such implementation:

```javascript
// api-client.js
import RailsRanger from 'rails-ranger'

const client = new RailsRanger

export default {
  client,

  users: {
    list(params) {
      return this.client.list('users', params)
    }
  }

  blogPosts: {
    list(params) {
      return this.client.list('blogPosts', params)
    }
  }
}
```

```javascript
// some-front-end-component.js
import api from 'api-client'

api.users.list({ limit: 3 }).then((response) => {
  const users = response.data
})
```
<br>

## Options
As the first argument when creating a new instance of Rails Ranger you can pass an object of options to customize the behavior of the client.

### dataTransform
**default: true**

By default RailsRanger will convert camelCased keys in your jsons to snake_case when sending a request to Rails, and will convert the Rails response back from snake_case to camelCase for better usage within your javascript code.

You can disable this behavior by setting `dataTransform` to false:

```javascript
const api = new RailsRanger({ dataTransform: false })
```

---
### axios
**default: {}**

Any object passed to the `axios` option will be handled to **Axios**.
Here an example using the `baseUrl` configuration of Axios:

```javascript
const api = new RailsRanger({ axios: { baseUrl: 'http://myapp.com/api/v1' } })

api.list('users')
// => GET request to http://myapp.com/api/users
```

#### See more configuration options in the [Axios documentation](https://github.com/mzabriskie/axios#request-config)
<br>

## Use Rails Ranger just for path building
You don't need to use Rails Ranger as an ajax client if you don't want to. It can also be used just to generate the resource routes and then make the request with another tool. The following is an example of this usage:

```javascript
import { RouteBuilder } from RailsRanger
const routes = new RouteBuilder

routes.create('users', { name: 'John' })
// => { path: '/users', params: { name: 'John' }, method: 'post' }

routes.show('users', { id: 1, hidePassword: true })
// => { path: '/users/1?hide_password=true', params: {}, method: 'get' }

routes.get('/:api/documentation', { api: 'v1', page: 3 })
// => { path: 'v1/documentation?page=3', params: {}, method: 'get' }
```
<br>

## Nested resources
You can access your nested resources by using the `.resource` function:

```javascript
api.resource('users').list('blogPosts')
//=> GET request to /users/blog_posts


api.resource('users', 1).list('blogPosts')
//=> GET request to /users/1/blog_posts
```

## Available actions

### List/Index
```javascript
api.list('users', { limit: 3 })
// => GET request to /users?limit=3

api.index('users', { limit: 3 })
// => GET request to /users?limit=3
```

### Show
```javascript
api.show('users', { id: 1 })
// => GET request to /users/1
```

### New
```javascript
api.new('users')
// => GET request to /users/new
```

### Create
{'fraction_non_alphanumeric': 0.1446295332292209, 'fraction_numerical': 0.0029498525073746312, 'mean_word_length': 4.411737089201878, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 43, 'https://': 30, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '155504', 'n_tokens_mistral': 3795, 'n_tokens_neox': 3536, 'n_words': 1186}