A minimal higher-level wrapper around Fetch API
Built on top of isomorphic-fetch
npm install hifetch
Hifetch is optimized for JSON API.
You can fetch, process and consume JSON response with minimal custom options.
import hifetch from 'hifetch';
// GET http://www.mydomain.com/users/1/?mobile=true
// + Response 200 (application/json; charset=utf-8)
// + Headers
// X-API-Version: 1.0
// + Body
// {
// "status": 0,
// "username": "xxx"
// }
hifetch({
url: 'http://www.mydomain.com/users/1/',
query: {
mobile: true,
},
jwtToken: '...', // Authorization header with the Bearer authentication
headers: { // Custom request headers
'X-Requested-With': 'XMLHttpRequest',
},
timeout: 10000,
}).send().then(result => {
// result:
// {
// "status": 0,
// "username": "xxx"
// }
}).catch(errorResult => {
// errorResult:
// {
// "status": 5,
// "message": "[TIMEOUT ERROR] limit: 10000"
// }
// or
// {
// "status": 1,
// "message": "[INTERNAL JS ERROR] error message that generated by Hifetch own code"
// "error": Error,
// }
});
By default, Hifetch supports JSON response in Goolge JSON Style
// GET http://www.mydomain.com/users/wrong-id/
// + Response 400 (application/json; charset=utf-8)
// + Body
// {
// "error": {
// "code": 400,
// "message": "User Not Found", // human readable message
// "errors": [{
// "reason": "ResourceNotFoundException", // Unique Identifier
// "message": "User Not Found", // human readable message
// }]
// }
// }
hifetch({
url: 'http://www.mydomain.com/users/wrong-id/',
disableStatusValidator: true,
}).send().then(result => {
// ...
}).catch(errorResult => {
// errorResult:
// {
// "status": 3,
// "message": `[REMOTE ERROR] reason: ResourceNotFoundException, code: 400, message: User Not Found`,
// "originMessage": "User Not Found",
// "reason": "ResourceNotFoundException",
// "errors": [{ ... }],
// }
});
// GET http://www.mydomain.com/users/1/
// + Response 200 (application/json; charset=utf-8)
// + Body
// {
// "data": {
// "otherDataA": ...
// "otherDataB": ...
// },
// }
hifetch({
url: 'http://www.mydomain.com/users/1/',
}).send().then(result => {
// result:
// {
// "otherDataA": ...
// "otherDataB": ...
// }
});
Hifetch also supports JSON response with unix-style exit status
A zero exit status indicates succeeded. A nonzero exit status indicates failure (Hifetch only supports negative number)
You can use this style by responseStyle
option
// GET http://www.mydomain.com/users/wrong-id/
// + Response 200 (application/json; charset=utf-8)
// + Body
// {
// "status": -1, // Unique Identifier
// "message": "User Not Found" // human readable message
// "otherData": ...
// }
hifetch({
url: 'http://www.mydomain.com/users/wrong-id/',
responseStyle: 'unix',
}).send().then(result => {
// ...
}).catch(errorResult => {
// errorResult:
// {
// "status": -1,
// "message": "User Not Found"
// "otherData": ...
// }
});
// GET http://www.mydomain.com/users/1/
// + Response 200 (application/json; charset=utf-8)
// + Body
// {
// "status": 0,
// "otherDataA": ...
// "otherDataB": ...
// }
hifetch({
url: 'http://www.mydomain.com/users/1/',
query: {
mobile: false,
},
responseStyle: 'unix',
}).send().then(result => {
// result:
// {
// "status": 0,
// "otherDataA": ...
// "otherDataB": ...
// }
});
You can disable this feature by disableResponseStyle
option
HTTP status code validation
hifetch({
url: 'http://www.mydomain.com/nonexistent-url/',
// the following code is the default value of `validateStatus`, so it should be omitted
validateStatus(status) {
return status >= 200 && status < 300;
},
}).send().then(result => {
// ...
}).catch(errorResult => {
// errorResult:
// {
// "status": 2,
// "message": "[FETCH ERROR] 404 Not Found"
// "httpStatus": 404,
// "httpStatusText": "Not Found",
// }
});
Error response caused by user-defined hook function (validateStatus
, parser
, handler
, success
, error
)
hifetch({
url: 'http://www.mydomain.com/users/1/',
handler() {
throw new Error();
},
}).send().then(result => {
// ...
}).catch(errorResult => {
// errorResult:
// {
// "status": 4,
// "message": "[CUSTOM JS ERROR] error message that caused by user-defined hook function"
// "error": Error,
// }
});
By default, Hifetch directly uses response body as the result.
When the response body is JSON object format, you can merge some response headers into the result.
// GET http://www.mydomain.com/users/1/
// + Response 200 (application/json; charset=utf-8)
// + Headers
// X-API-Version: 1.0
// + Body
// {
// "status": 0,
// "username": "xxx"
// }
hifetch({
url: 'http://www.mydomain.com/users/1/',
mergeHeaders: {
version: 'X-API-Version',
},
}).send().then(res => {
// result:
// {
// "status": 0,
// "username": "xxx"
// "version": "1.0",
// }
});
When enableMeta
is true, the result is a meta object.
// GET http://www.mydomain.com/users/1/
// + Response 200 (application/json; charset=utf-8)
// + Headers
// X-API-Version: 1.0
// + Body
// {
// "status": 0,
// "username": "xxx"
// }
hifetch({
url: 'http://www.mydomain.com/users/1/',
mergeHeaders: {
version: 'X-API-Version',
},
enableMeta: true,
// enableResponseObject: true,
}).send().then(res => {
// result:
// {
// "status": 0,
// "httpStatus": 200,
// "httpStatusText": "",
// "url": "http://www.mydomain.com/users/1/",
// "headers": {
// "x-api-version": "1.0",
// "content-type": "application/json; charset=utf-8",
// },
// "data": {
// "status": 0,
// "username": "xxx"
// },
// "response": ResponseObject, // if `enableResponseObject` is true
// }
});
hifetch({
url: 'http://www.mydomain.com/users/1/',
mergeHeaders: {
version: 'X-API-Version',
},
filterHeaders: {
'content-type': true,
},
enableMeta: true,
}).send().then(res => {
// result:
// {
// "status": 0,
// "httpStatus": 200,
// "httpStatusText": "",
// "url": "http://www.mydomain.com/users/1/",
// "headers": {
// "content-type": "application/json; charset=utf-8",
// },
// "data": {
// "status": 0,
// "username": "xxx"
// },
// }
});
Use custom responseType
and parser
to fetch HTML string:
hifetch({
url: 'http://www.mydomain.com/profile/1/',
responseType: 'html', // or 'text/html',
parser(response) { // you muse provide a custom parser for Fetch API's response
return response.text();
},
Post JSON with urlencoded body
hifetch({
url: 'http://www.mydomain.com/users/1/actions/createByUrlencoded',
method: 'post',
query: {
mobile: true,
},
data: { // request body
name: 'yy',
},
Post JSON with JSON-encoded body
hifetch({
url: 'http://www.mydomain.com/users/1/actions/createByJSON',
method: 'post',
query: {
mobile: true,
},
data: { // request body
name: 'yy',
},
dataType: 'json', // or 'application/json',
Post form-data body
const formData = new FormData();
formData.append('name', 'yy');
hifetch({
url: 'http://www.mydomain.com/users/1/actions/createByFormData',
method: 'post',
query: {
mobile: true,
},
data: formData, // request body
or
hifetch({
url: 'http://www.mydomain.com/users/1/actions/createByFormData',
method: 'post',
query: {
mobile: true,
},
data: { // request body
name: 'yy',
},
dataType: 'form', // or 'multipart/form-data',
Post form-data body with files
hifetch({
url: 'http://www.mydomain.com/users/1/actions/createByFormData',
method: 'post',
query: {
mobile: true,
},
data: { // request body
name: 'yy',
avatar: imageFile,
},
or
const formData = new FormData();
formData.append('name', 'yy');
formData.append('photos', imageFile1);
formData.append('photos', imageFile2);
hifetch({
url: 'http://www.mydomain.com/users/1/actions/createByFormData',
method: 'post',
query: {
mobile: true,
},
data: formData, // request body
Custom validator and processor for response data
hifetch({
//...
handler: (res, headers) => {
if (res.xx) {
throw new Error(res.xx);
}
return Object.assign(headers, data);
},
url
- Required
method
- Default:
'get'
- Default:
query
- Type: plain object
dataType
- Default:
'application/x-www-form-urlencoded'
- Custom
'Content-Type'
header
- Default:
data
- Type: plain object, FormData object or String
- When using FormData,
dataType
can be omitted (always be 'multipart/form-data')
FormData
- Required in node.js environment
- FormData class
headers
- Other custom request headers
jwtToken
- Add JWT header
responseType
- Default:
'application/json'
- Custom
'Accept'
header
- Default:
responseStyle
- Type: 'google' | 'unix'
- Default:
'google'
- Automatically processing the JSON response based on special style guide
mergeHeaders
- Type: plain object
- Default: null
- Merge some response headers into the JSON object reponse
- Example:
{ poweredBy: 'X-Powered-By' }
filterHeaders
- Type: plain object
- Default: null
- Pick some response headers.
- Example:
{ 'X-Powered-By': true }
or{ 'x-powered-by': true }
timeout
- Millisecond
enableCookies
- Type: Boolean
- Default: false
- Automatically send cookies
disableCORS
- Type: Boolean
- Default: false
disableStatusValidator
- Type: Boolean
- Default: false
- Skip the
validateStatus
hook
disableResponseStyle
- Type: Boolean
- Default: false
- Disable the automatic processing (like 'REMOTE ERROR') triggered by the special format of JSON response
enableMeta
- Type: Boolean
- Default: false
- Embed response body into a meta object
enableResponseObject
- Type: Boolean
- Default: false
- Like
enableMeta
, plus the response object
validateStatus
- Default:
status >= 200 && status < 300
- Custom validator for acceptable HTTP response status code
- Default:
parser
- Default:
response => response.json()
- Default:
handler
- Custom validator and processor for response data
success
- Default:
res => res
- Default:
error
- Default:
res => Promise.reject(res)
- Default:
send()
- Return: Promise
- Automatically nterrupt latest outstanding request each time it's called
cancel()
- Interrupt latest outstanding request, nothing happen
error()
- Interrupt latest outstanding request, trigger error callback
See actions.spec.js for more detail.
npm run lint
npm run test