
Product
Introducing Repository Access Permissions and Custom Roles
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.
fetch-with-json
Advanced tools
Some tweaks to the Fetch API to make it easier to communicate with the server using JSON.
Some tweaks to the Fetch API to make it easier to communicate with the server using JSON.
Using this library, you don't need to manually set the request header "Content-Type" to "application/json" every time you send JSON to the server.
This library does the following for you:
json field in the options) with JSON.stringify before sending it to the server as request body. See the example here.Content-Type to application/json and Accept to application/json, */* if they are not set.Content-Type is and assign the parsed result to response.json. If error has be thrown during parsing, response.json will be set to the text of the original response body, and the error will be assigned to response.error.This library is a zero dependencies module and will always be. This library only extends the fetch options, not overrides it. So you can use the functionality provided by the original Fetch API. For example, you can use this library to upload files just like you would with Fetch API. And you can get the original Response if you want.
Examples:
npm i fetch-with-json
import request from 'fetch-with-json'
request({
method: 'POST',
url: '/posts',
json: {
title: 'Fetch API',
content: 'The Fetch API provides an interface for fetching resources.'
}
}).then((res) => {
console.log(`post created, id = ${res.json.id}`)
})
The type of res is FetchResponse and the json field of res is the parsed JSON object.
import request from 'fetch-with-json'
// GET /posts?page=1&size=10&category=typescript
request({
url: '/posts',
query: {
page: 1,
size: 10,
category: 'typescript'
}
})
The query object will be encoded to query string with a default encodeQuery function. If the default encodeQuery function does not meet your needs, you can override it by setting the encodeQuery option. This is very useful when you are creating your own request method based on this library. See the coming example for more details.
import qs from 'qs'
import fetchWithJSON, { FetchOptions } from 'fetch-with-json'
// Encode query with `qs` module
function encodeQuery(query: Record<string, any>) {
return qs.stringify(query)
}
export default async function request(options: FetchOptions) {
// Set baseURL if it is not set
options.baseURL = options.baseURL || 'https://example.com/v2'
// Set encodeQuery if it is not set to override the default one
options.encodeQuery = options.encodeQuery || encodeQuery
// Extend the original headers
options.headers = new Headers(options.headers)
// Set X-My-Custom-Header if it is not set
if (!options.headers.has('X-My-Custom-Header')) {
options.headers.set('X-My-Custom-Header', 'header-value')
}
return fetchWithJSON(options)
}
// GET https://example.com/v2/posts
request({ url: '/posts' })
import request from 'fetch-with-json'
const formData = new FormData()
const fileField = document.querySelector('input[type="file"]')
formData.append('avatar', fileField.files[0])
// You can add other fields, e.g:
// formData.append("username", "abc123");
// The Fetch API will set request header "Content-Type" to
// "multipart/form-data" automatically if the type of body
// is FormData.
request({
method: 'POST',
url: '/users/profile',
body: formData
}).then((res) => {
console.log(res)
})
Please note that we are using the body field to upload the FormData instead of using the json field. The body field is declared in the parameters of the Fetch API. When body is set (not null or undefined), the json field will be ignored.
If you want to get the original Response returned by the Fetch API, please set the second parameter to true, below is an example.
import request from 'fetch-with-json'
request({ url: '/posts/1' }, true).then((res) => {
// The type of res is Response
console.log(res)
})
The request method has two declarations. The primary one is:
function request<T = any>(options: FetchOptions): Promise<FetchResponse<T>>
The above one will always convert the Response to FetchResponse. If you want to get the original Response, you can use the second declaration:
function request(options: FetchOptions, rawResponse: true): Promise<Response>
Put them together, below is the declaration of FetchMethod:
interface FetchMethod {
<T = any>(options: FetchOptions): Promise<FetchResponse<T>>
<T = any>(options: FetchOptions, rawResponse: true): Promise<Response>
}
Note: We add generic type to the second one just to keep it consistent with the first one (the generic type for the second one actually has no effects).
The declaration of FetchOptions is:
interface FetchOptions extends RequestInit {
/**
* The request url.
*/
url?: string
/**
* The data to send to the server. The data will be stringified using
* `JSON.stringify` before being sent to the server and the `Content-Type`
* request header will be set to `application/json` if not set.
*
* If the `body` field is set (not `null` or `undefined`), the `json`
* field will be ignored and we will not set the `Content-Type` header.
*/
json?: any
/**
* The base URL to prepend to `url` if `url` is a relative url.
*/
baseURL?: string
/**
* The value to be encoded to query string to append to the url.
*/
query?: Record<string, any>
/**
* A function to encode the `query` value.
* A query string must be returned without a leading question mark.
* If this function is not set, the default one will be used.
*/
encodeQuery?: (query: Record<string, any>) => string
}
For the many other options (the options declared in the RequestInit type) provided by the original Fetch API, please click here to read the documentation of the fetch parameters on the MDN website.
The declaration of FetchResponse is:
interface FetchResponse<T = any> {
/**
* The `Headers` object associated with the response.
*/
headers: Headers
/**
* The response data. Parsed from the response body text with `JSON.parse`.
* If parsing fails, this field will be set to the response body text and
* the `error` field of the response will be set to the error thrown
* during the parsing.
*/
json: T
/**
* The error thrown while parsing the response body text with `JSON.parse`.
* If no error has been thrown, the value of this field is `undefined`.
*/
error?: Error
/**
* A boolean indicating whether the response was successful (status in the
* range 200 – 299) or not.
*/
ok: boolean
/**
* Indicates whether or not the response is the result of a redirect
* (that is, its URL list has more than one entry).
*/
redirected: boolean
/**
* The status code of the response.
*/
status: number
/**
* The status message corresponding to the status code. (e.g., OK for 200).
*/
statusText: string
/**
* The original response body text.
*/
text: string
/**
* The type of the response (e.g., basic, cors).
*/
type: ResponseType
/**
* The URL of the response.
*/
url: string
}
encodeQuery functionHere is the implementation of the default encodeQuery function for your reference.
function defaultEncodeQuery(query: Record<string, any>) {
const hasOwn = Object.prototype.hasOwnProperty
const params = new URLSearchParams()
for (const key in query) {
if (hasOwn.call(query, key)) {
const val = query[key]
if (val != null) {
if (Array.isArray(val)) {
val.forEach((elem) => params.append(key, '' + elem))
} else {
params.append(key, '' + val)
}
}
}
}
return params.toString()
}
FAQs
Some tweaks to the Fetch API to make it easier to communicate with the server using JSON.
The npm package fetch-with-json receives a total of 28 weekly downloads. As such, fetch-with-json popularity was classified as not popular.
We found that fetch-with-json demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer 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.

Product
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.

Product
Socket MCP now lets AI assistants review org alerts, investigate threats using the Socket threat feed, and inspect package files in addition to dependency scoring.

Product
Socket Firewall blocks malicious VS Code and Open VSX extensions before install, protecting developers from compromised editor marketplaces.