Security News
New Python Packaging Proposal Aims to Solve Phantom Dependency Problem with SBOMs
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
restful.js
Advanced tools
A pure JS client for interacting with server-side RESTful resources. Think Restangular without Angular.
A pure JS client for interacting with server-side RESTful resources. Think Restangular without Angular.
It is available with bower or npm:
bower install restful.js
npm install restful.js
Include restful.min.js
to the HTML, and the restful
object is now available in the global scope:
<script type="text/javascript" src="/path/to/bower_components/restful.js/dist/restful.min.js"></script>
Alternately, you can use RequireJS or Browserify to avoid global scoping.
var restful = require('restful.js');
Start by defining the base endpoint for an API, for instance http://api.example.com
.
var api = restful('api.example.com');
You can add headers, port, custom protocol, or even a prefix (like a version number):
var api = restful('api.example.com')
.header('AuthToken', 'test') // set global header
.prefixUrl('v1')
.protocol('https')
.port(8080);
// resource now targets `https://api.example.com:8080/v1`
A collection is an API endpoint for a list of entities, for instance http://api.example.com/articles
. Create it using the all(name)
syntax:
var articlesCollection = api.all('articles'); // http://api.example.com/articles
articlesCollection
is just the description of the collection, the API wasn't fetched yet.
A member is an API endpoint for a single entity, for instance http://api.example.com/articles/1
. Create it using the one(name, id)
syntax:
var articleMember = api.one('articles', 1); // http://api.example.com/articles/1
Just like above, articleMember
is a description, not an entity.
You can chain one()
and all()
to target the required collection or member:
var articleMember = api.one('articles', 1); // http://api.example.com/articles/1
var commentsCollection = articleMember.all('comments'); // http://api.example.com/articles/1/comments
In case you need to set a custom endpoint URL, you can use oneUrl
or allUrl
methods.
var articleMember = api.oneUrl('articles', 'http://custom.url/article?id=1'); // http://custom.url/article?id=1
var articlesCollection = api.allUrl('articles', 'http://custom.url/article/list'); // http://custom.url/article/list
Once you have collections and members endpoints, fetch them to get entities. Restful.js exposes get()
and getAll()
methods for fetching endpoints. Since these methods are asynchronous, they return a Promise (based on the ES6 Promise specification) for response.
var articleMember = api.one('articles', 1); // http://api.example.com/articles/1
articleMember.get().then(function(response) {
var articleEntity = response.body();
var article = articleEntity.data();
console.log(article.title); // hello, world!
});
var commentsCollection = articleMember.all('comments'); // http://api.example.com/articles/1/comments
commentsCollection.getAll().then(function(response) {
var commentEntities = response.body();
commentEntities.forEach(function(commentEntity) {
var comment = commentEntity.data();
console.log(comment.body);
})
});
Tip: You can describe a member based on a collection and trigger the API fetch at the same time by calling get(id)
:
// fetch http://api.example.com/articles/1/comments/4
var articleMember = api.one('articles', 1);
var commentMember = articleMember.one('comments', 4);
commentMember.get().then(function(response) {
//
});
// equivalent to
var commentsCollection = articleMember.all('comments');
commentsCollection.get(4).then(function(response) {
//
});
A response is made from the HTTP response fetched from the endpoint. It exposes status()
, headers()
, and body()
methods. For a GET
request, the body
method will return one or a an array of entities. Therefore you can disable this hydration by calling body(false)
.
An entity is made from the HTTP response data fetched from the endpoint. It exposes a data()
method:
var articleCollection = api.all('articles'); // http://api.example.com/articles
// http://api.example.com/articles/1
api.one('articles', 1).get().then(function(response) {
var articleEntity = response.body();
// if the server response was { id: 1, title: 'test', body: 'hello' }
var article = articleEntity.data();
article.title; // returns `test`
article.body; // returns `hello`
// You can also edit it
article.title = 'test2';
// Finally you can easily update it or delete it
articleEntity.save(); // will perform a PUT request
articleEntity.remove(); // will perform a DELETE request
}, function(response) {
// The reponse code is not >= 200 and < 400
throw new Error('Invalid response');
});
You can also use the entity to continue exploring the API. Entities expose several other methods to chain calls:
entity.one(name, id)
: Query a member child of the entity.entity.all(name)
: Query a collection child of the entity.entity.url()
: Get the entity url.entity.save()
: Save the entity modifications by performing a POST request.entity.remove()
: Remove the entity by performing a DELETE request.entity.id()
: Get the id of the entity.var articleMember = api.one('articles', 1); // http://api.example.com/articles/1
var commentMember = articleMember.one('comments', 3); // http://api.example.com/articles/1/comments/3
commentMember.get()
.then(function(response) {
var commentEntity = response.body();
// You can also call `all` and `one` on an entity
return comment.all('authors').getAll(); // http://api.example.com/articles/1/comments/3/authors
}).then(function(response) {
var authorEntities = response.body();
authorEntities.forEach(function(authorEntity) {
var author = authorEntity.data();
console.log(author.name);
});
});
Restful.js uses an inheritance pattern when collections or members are chained. That means that when you configure a collection or a member, it will configure all the collection an members chained afterwards.
// configure the api
api.header('AuthToken', 'test');
var articlesCollection = api.all('articles');
articlesCollection.get(1); // will send the `AuthToken` header
// You can configure articlesCollection, too
articlesCollection.header('foo', 'bar');
articlesCollection.one('comments', 1).get(); // will send both the AuthToken and foo headers
Restful.js exposes similar methods on collections, members and entities. The name are consistent, and the arguments depend on the context.
getAll ( [ params [, headers ]] )
: Get a full collection. Returns a promise with an array of entities.get ( id [, params [, headers ]] )
: Get a member in a collection. Returns a promise with an entity.post ( data [, headers ] )
: Create a member in a collection. Returns a promise with the response.put ( id, data [, headers ] )
: Update a member in a collection. Returns a promise with the response.delete ( id [, headers ] )
: Delete a member in a collection. Returns a promise with the response.patch ( id, data [, headers ] )
: Patch a member in a collection. Returns a promise with the response.head ( id, [, headers ] )
: Perform a HEAD request on a member in a collection. Returns a promise with the response.url ()
: Get the collection url.addResponseInterceptor ( interceptor )
: Add a response interceptor. You can only alter data and headers.addRequestInterceptor ( interceptor )
: Add a request interceptor.addFullResponseInterceptor ( interceptor )
: Add a full response interceptor. You can alter data and headers.addFullRequestInterceptor ( interceptor )
: Add a full request interceptor. You can alter params, headers, data, method and url.header ( name, value )
: Add a header.// http://api.example.com/articles/1/comments/2/authors
var authorsCollection = api.one('articles', 1).one('comments', 2).all('authors');
authorsCollection.getAll().then(function(authorEntities) { /* */ });
authorsCollection.get(1).then(function(authorEntity) { /* */ });
get ( [ params [, headers ]] )
: Get a member. Returns a promise with an entity.put ( data [, headers ] )
: Update a member. Returns a promise with the response.delete ( [ headers ] )
: Delete a member. Returns a promise with the response.patch ( data [, headers ] )
: Patch a member. Returns a promise with the response.head ( [ headers ] )
: Perform a HEAD request on a member. Returns a promise with the response.one ( name, id )
: Target a child member in a collection name
.all ( name )
: Target a child collection name
.url ()
: Get the member url.addResponseInterceptor ( interceptor )
: Add a response interceptor.addRequestInterceptor ( interceptor )
: Add a request interceptor. You can only alter data and headers.addFullResponseInterceptor ( interceptor )
: Add a full response interceptor. You can alter data and headers.addFullRequestInterceptor ( interceptor )
: Add a full request interceptor. You can alter params, headers, data, method and url.header ( name, value )
: Add a header.// http://api.example.com/articles/1/comments/2
var commentMember = api.one('articles', 1).one('comments', 2);
commentMember.get().then(function(commentEntity) { /* */ });
commentMember.delete().then(function(data) { /* */ });
A response or request interceptor is a callback which looks like this:
resource.addRequestInterceptor(function(data, headers, method, url) {
// to edit the headers, just edit the headers object
// You always must return the data object
return data;
});
A full request interceptor is a callback which looks like this:
resource.addFullRequestInterceptor(function(params, headers, data, method, url) {
//...
// all args had been modified
return {
params: params,
headers: headers,
data: data,
method: method,
url: url
};
// just return modified arguments
return {
headers: headers,
data: data
};
});
A full response interceptor is a callback which looks like this:
resource.addFullResponseInterceptor(function(data, headers, method, url) {
// all args had been modified (method and url is read only)
return {
headers: headers,
data: data
};
// just return modified arguments
return {
headers: headers
};
});
response.status()
: Get the HTTP status code of the responseresponse.headers()
: Get the HTTP headers of the responseresponse.body()
: Get the HTTP body of the response. If it is a GET
request, it will hydrate some entities. To get the raw body call it with false
as argument.entity.data()
: Get the JS object unserialized from the response body (which must be in JSON)entity.one(name, id)
: Query a member child of the entity.entity.all(name)
: Query a collection child of the entity.entity.url()
: Get the entity url.entity.id()
: Get the id of the entity.entity.save ( [ headers ] )
: Update the member link to the entity. Returns a promise with the response.entity.remove ( [ headers ] )
: Delete the member link to the entity. Returns a promise with the response.// http://api.example.com/articles/1/comments/2
var commentMember = api.one('articles', 1).one('comments', 2);
commentMember.get().then(function(commentEntity) {
commentEntity.save();
commentEntity.remove();
});
To deal with errors, you must use the catch
method on any of the returned promises:
var commentMember = resource.one('articles', 1).one('comments', 2);
commentMember
.get()
.then(function(commentEntity) { /* */ })
.catch(function(err) {
// deal with the error
});
Install dependencies:
make install
To rebuild the minified JavaScript you must run: make build
.
During development you can run make watch
to trigger a build at each change.
make test
All contributions are welcome and must pass the tests. If you add a new feature, please write tests for it.
This application is available under the MIT License, courtesy of marmelab.
FAQs
A pure JS client for interacting with server-side RESTful resources. Think Restangular without Angular.
The npm package restful.js receives a total of 83 weekly downloads. As such, restful.js popularity was classified as not popular.
We found that restful.js demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
Security News
Socket CEO Feross Aboukhadijeh discusses open source security challenges, including zero-day attacks and supply chain risks, on the Cyber Security Council podcast.
Security News
Research
Socket researchers uncover how threat actors weaponize Out-of-Band Application Security Testing (OAST) techniques across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.