A Ruby on Rails REST client
npm install rails-ranger#### Github Repository | Documentation





Rails Ranger is a thin layer on top of Axios, which gives you an opinionated interface to query APIs built with Ruby on Rails.
bash
npm install --save rails-ranger
`or
`bash
yarn add rails-ranger
`
Getting started
If you prefer a blog post, checkout our getting started guide here.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',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
}
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 automatically to camelCase, as preferred in Javascript.
> Observation: you can use
api.index('users') as well. The list function is just an alias for it.
$3
You must setup the headers correctly, passing down the content type and accept keys as application/json (as shown in the example above) for Rails to serve the endpoint in the json format instead of presuming the HTTP default.$3
`javascript
api.resource(users, 1).list('blogPosts', { someParameter: false })
// => GET request to /users/1/blog_posts?some_parameter=false
`
$3
You can build your own client object to centralize the API routes used by your front-end app.This is indeed recommended for non-trivial applications, to avoid duplication, allow manipulating the parameters before performing the request and make your life easier in the event of removal/replacement of 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 {
users: {
list(params) {
return client.list('users', params)
}
}
blogPosts: {
list(params) {
return 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
})
`
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.$3
default: trueBy 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 })
`---
$3
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
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 RouteBuilderroutes.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' }
`
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
`
Namespaced routes
The .namespace function can help you to build a path nested within a Rails namespace:`javascript
api.namespace('users').list('blogPosts')
//=> GET request to /users/blog_posts
api.namespace('admin_roles/:type', { type: 1 }).list('blogPosts')
//=> GET request to /admin_roles/1/blog_posts
`
Available actions
$3
`javascript
api.list('users', { limit: 3 })
// => GET request to /users?limit=3api.index('users', { limit: 3 })
// => GET request to /users?limit=3
`$3
`javascript
api.show('users', { id: 1 })
// => GET request to /users/1
`$3
`javascript
api.new('users')
// => GET request to /users/new
`$3
`javascript
api.create('users', { email: 'john@doe.com' })
// => POST request to /users
`$3
`javascript
api.edit('users', { id: 1 })
// => GET request to /users/1/edit
`$3
`javascript
api.update('users', { id: 1, name: 'John Doe' })
// => PATCH request to /users/1
`$3
`javascript
api.destroy('users', { id: 1 })
// => DELETE request to /users/1
`
Available HTTP methods
$3
`javascript
api.get('users/:id', { id: 1, hidePassword: true })
// => GET request to users/1&hide_password=true
`$3
`javascript
api.post('users/:id', { id: 1, name: 'John' })
// => POST request to users/1 with a JSON payload containing: { "name": "John" }
`$3
`javascript
api.patch('users/:id', { id: 1, name: 'John' })
// => PATCH request to users/1 with a JSON payload containing: { "name": "John" }
`$3
`javascript
api.put('users/:id', { id: 1, name: 'John' })
// => PUT request to users/1 with a JSON payload containing: { "name": "John" }
`$3
`javascript
api.delete('users/:id', { id: 1, hidePassword: true })
// => DELETE request to users/1&hide_password=true
`
Request Cancellation
Since rails-ranger is built on top of Axios, request cancellation works the same way.
`javascript
import api from 'api-client'import axios from 'axios';
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
const request = api.get('/users/:id', {id: 1}, {cancelToken: source.token})
request.cancel = (optionalMessage) => source.cancel(optionalMessage);
``