amareis / another-rest-client Goto Github PK
View Code? Open in Web Editor NEWSimple pure TypeScript REST API client that makes your code lesser and more beautiful than without it.
License: MIT License
Simple pure TypeScript REST API client that makes your code lesser and more beautiful than without it.
License: MIT License
Hi there,
I tried using this library and following code yielded an error:
const RestClient = require('another-rest-client');
global.XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
let api = new RestClient('http://localhost:8082/engine-rest');
api.on('error', function(err) {
console.log('err');
});
api.res('engine');
api.engine.get().then(function(result) {
console.log(result);
}, function(reason) {
console.log(reason);
});
When debugging the code in Visual Studio Code the promise resolved successfully with result
being undefined. Also the error
callback was not called.
The error displayed on the console is the following:
SyntaxError: Unexpected token u in JSON at position 0
at parse (native)
at safe (c:\Users\felix\Desktop\js-test\node_modules\another-rest-client\rest-client.js:80:17)
at _createClass.value.xhr.onreadystatechange (c:\Users\felix\Desktop\js-test\node_modules\another-rest-client\rest-client.js:157:67)
at exports.XMLHttpRequest.dispatchEvent (c:\Users\felix\Desktop\js-test\node_modules\xmlhttprequest\lib\XMLHttpRequest.js:591:25)
at setState (c:\Users\felix\Desktop\js-test\node_modules\xmlhttprequest\lib\XMLHttpRequest.js:610:14)
at IncomingMessage.<anonymous> (c:\Users\felix\Desktop\js-test\node_modules\xmlhttprequest\lib\XMLHttpRequest.js:447:13)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
Trying the same query in postman works just fine. The result body is:
[{"name":"default"}]
With following headers:
Cache-Control →no-cache
Content-Type →application/json
Date →Mon, 05 Mar 2018 18:09:49 GMT
Transfer-Encoding →chunked
Especially as the promise resolves successfully I don't see me doing anything wrong. But if so I'd be happy to see my error pointed out to me.
Best regards
Felix
If you need, for example, get response headers, you can do so:
let pageLinks = {}
api.on('success', x => pageLinks.links = x.getResponseHeader('Link'))
let commits = await api.repos(action.repo.full_name).commits.get()
api.off('success')
console.log(pageLinks.links)
But it can be broken easily if another request emit success
after this success
event, but before console.log
. So we need method for attach event to strictly defined request, it's also fits #3
I have some troubles with Authorization headers in XMLHttpRequest using Auth0. When I try to renew token from Auth0 after page loaded with this code:
api.on('request', xhr => {
xhr.setRequestHeader('Authorization', `Bearer ${authResult.accessToken}`);
})
I expect that new token will replace the old one, but it's add like: Bearer OLDTOKEN, NEWTOKEN
.
Can you help with replace XMLHttpRequest or provide example how to use tokens and when and how I should replace it?
Is it possible to get the progress of a (large) JSON response?
Update:
I've tried implementing the example on whatwg.org, but no success. I don't see any calls to onprogress
in my browser console. Would this be something provided by the server? (I'm using Python/Flask, and doing some research there also).
api.api().myapi()
.get()
.on('response', function(res) {
console.log(res.onprogress) // returns 'null'
res.onprogress = function(pe) {
console.log(pe); // not reached
if (pe.lengthComputable) {
console.log(pe.loaded) // not reached
}}})
.then(function (_json) { do_stuff(_json) })
Just like this (maybe like your awesome fluent api)
In this project: https://github.com/JustinBeckwith/retry-axios
and add methods like get, put, and so on doing their job.
source: https://github.com/JustinBeckwith/retry-axios
`raxConfig: {
// Retry 3 times on requests that return a response (500, etc) before giving up. Defaults to 3.
retry: 3,
// Retry twice on errors that don't return a response (ENOTFOUND, ETIMEDOUT, etc).
noResponseRetries: 2,
// Milliseconds to delay at first. Defaults to 100. Only considered when backoffType is 'static'
retryDelay: 100,
// HTTP methods to automatically retry. Defaults to:
// ['GET', 'HEAD', 'OPTIONS', 'DELETE', 'PUT']
httpMethodsToRetry: ['GET', 'HEAD', 'OPTIONS', 'DELETE', 'PUT'],
// The response status codes to retry. Supports a double
// array with a list of ranges. Defaults to:
// [[100, 199], [429, 429], [500, 599]]
statusCodesToRetry: [[100, 199], [429, 429], [500, 599]],
// If you are using a non static instance of Axios you need
// to pass that instance here (const ax = axios.create())
instance: ax,
// You can set the backoff type.
// options are 'exponential' (default), 'static' or 'linear'
backoffType: 'exponential',
// You can detect when a retry is happening, and figure out how many
// retry attempts have been made
onRetryAttempt: err => {
const cfg = rax.getConfig(err);
console.log(`Retry attempt #${cfg.currentRetryAttempt}`);
}
}`
Also there's another that has it's magic hidden like this:
https://github.com/softonic/axios-retry
Thanks in advance beacuse your awesome work
Доброго дня! а как сделать запрос на ура вида /foo-bar/rest
.foo-bar.rest не принимает.
Here shown, how to add some headers, before xhr gets sent. Can I access body POST
for encrypt data?
I don't see any way to set withCredentials to true to make request with cookies
In current project I heavily use your library. Sometimes I need to abort opened xhr requests.
I think you could add one time event listeners. Look at this
...
let openedXHR = [];
api.once('request', (xhr) => {
openedXHR.push(xhr);
})
api.res('account').res('balance').get().then(...)
openedXHR.forEach((xhr) => xhr.abort())
I can't use request
event, because RestClient
created once and reused everywhere.
How to renew JWT token?
To set authorization token I using:
api.on('request', function(xhr) {
xhr.setRequestHeader('Authorization', 'Bearer xxxTOKENxxx');
});
, but what I should do when get a new token?
var r = new RestClient('http://127.0.0.1:8080', {contentType: 'json'});
r.res('test')
r.test('ttt').get().then(function(k){alert(k)})
Chromium:
It works properly!
Firefox:
http://127.0.0.1:8080/test/ttt works properly. but when I use another-rest-client, It says:
SyntaxError: JSON.parse: unexcepted end of data at line 1 column 1 of the JSON data
but when I click on "edit and resend" and click on "send" without any change on headers, it return correct json in the response section without "SyntaxError: JSON.parse: unexcepted end of data at line 1 column 1 of the JSON data"
I'm using Bottle on Python as backend.
Yet another problem with this rest client is how to handle 'multipart/form-data' requests (e.g. we want to send post with files).
I was able to make formData, but the header contentType goes without boundary, so the server cannot parse the request.
rest.conf( {
contentType: 'multipart/form-data',
'multipart/form-data': {
encode: params => {
return Object.keys( params ).reduce( ( formData, paramName ) => {
formData.append( paramName, params[ paramName ] )
return formData
}, new FormData() )
}
}
} )
let result = await rest[ UPLOAD ].post( params )
Any idea how to handle it?
First of all I am not a javascript programmer.
I'm trying to make a simple call to a remote API on one of my servers. The code is below:
<html>
<head>
<script src="rest-client.js"></script>
<script>
window.onload = function () {
var api = new RestClient('https://api.asscontal.d.datanuvem.com/1.0');
api.on('request', function(xhr) {
xhr.setRequestHeader('Authorization', 'someapikey');
});
api.res({sites: 'sites'});
api.sites.get().then(function(k){alert(k)});
}
</script>
</head>
<body>
</body>
</html>
However, the browser reports the following errors:
XMLHttpRequest cannot load https://api.asscontal.d.datanuvem.com/1.0/sites. Response for preflight is invalid (redirect)
rest-client.js:167 XHR failed loading: GET "https://api.asscontal.d.datanuvem.com/1.0/sites".
_request @ rest-client.js:167
self.get @ rest-client.js:236
window.onload @ daspanel.html:12
daspanel.html:1 Uncaught (in promise) XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: function…}
The copy of res-client.js I'm using was obtained from this URL: https://raw.githubusercontent.com/Amareis/another-rest-client/master/rest-client.js
What am I doing wrong ?
Thank you.
As I can see I cant decamelize request params without own wrapper like
this.api['groups'].post(decamelizeKeys(data)).then(response => {
return camelizeKeys(response)
})
for each action
Hi! Very nice little and useful library!
Just as a proposal: why not to use Object.assign()
method in your RestClient.conf()
?
For example, you can move your default options to the separate file, import it, and then do something like this:
import settings from './settings'
....
conf(options={}) {
this._opts = Object.assign({}, settings, options)
}
Thanks and good luck!
Hi there and thanks for this library!
Is it possible to create a request with non-unique keys?
In the backend i want to use php-crud-api which has a filter feature which allows multiple filter[]
tags to combine conditions where the request would look something like
this.REST.endpoint.get({"filter[]": "name_id,eq," + 1337, "filter[]": "category_id,ge," + 4223, columns: "name, category, timestamp", order: "timestamp, asc" })...
results in the following XHR request:
XHR finished loading: GET "http://localhost/api.php/endpoint?filter%5B%5D=category_id%2Cge%2C4223&columns=name%2C%20category%2C%20timestamp&order=timestamp%2C%20asc"
so the first filter[]
part gets truncated.
Simple workaround i found was to explicetly name the indices of the array like
this.REST.endpoint.get({"filter[0]": "name_id,eq," + 1337, "filter[1]": "category_id,ge," + 4223, columns: "name, category, timestamp", order: "timestamp, asc" }).
but i still think itd be great if the library could take care of that or forward the URL unmodified.
Nice rest client!
But it only works with string response type, because of it's set by default.
So, when we try to work with blob (e.g. trying to get pdf from server), the blob from response goes incorrenct because of wrong xhr.responseType.
To get the pdf get viewed correctly, i had to set responseType manually and handle it in success hook:
rest
.on( 'request', xhr => {
xhr.responseType = 'blob'
} )
.on( 'success', xhr => {
const blob = new Blob( [ xhr.response ], { type: 'application/pdf' } )
FileSaver.saveAs( blob, `report.pdf` )
} )
.on( 'error', xhr => {
} )
[ REPORTS ]
.get( report )
Would be nice to configure the xhr.responseType property and get the results from xhr.reponse, not from xhr.reposneText as it is now.
api.res({'some-field: {SHORTCUT: 'someField}}).someField.get()
res
completely or make it working just like withRes
Hello,
I use the following snippet:
const api = new RestClient("http://localhost:8080/mgag/api");
api.res("users");
api.users.post(data).then(function (evt) {
console.log(evt);
}, function (other) {
alert("Unable to subscribe");
console.log(other);
console.log(other.getAllResponseHeaders());
});
Unfortunately, the other
parameter doesn't contain any useful headers even if the server sends them.
What I'm getting in Mozzilla Developper Console:
I want to grab the "Cause" header here.
Please note that I use CORS.
Firstly i like your library its small and works (i tried jquery.rest but it seems to force parameters on posts), but yours worked straight off, although i do slightly prefer how they support the .post(obj).done(fnDone).fail(fnFail) appraoch rather than .then(fnDone, fnFail) but all in all i still prefer yours.
Now the tiny issue (and fix?):
In WebAPI if you "return Ok()" or StatusCode 204 (no content) it doesnt set a content type, so there is an exception when your library tries to parse the content type ("Cannot read property 'split' of null(…)" on line 140).
This small mod appears to fix it without any unforeseen issues (though you can fix it in anyway you like obviously, since i do not have the time to learn to submit patches just wanted to make the fix as painless as possible).
from
var responseContentType = xhr.getResponseHeader('Content-Type').split(';')[0];
to
var responseContentType = (xhr.getResponseHeader('Content-Type') || "").split(';')[0];
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.