{"id":20494322,"url":"https://github.com/voltra/jsonclient","last_synced_at":"2026-06-10T07:31:19.814Z","repository":{"id":57186344,"uuid":"123697914","full_name":"Voltra/jsonclient","owner":"Voltra","description":"A JS HTTP client specialized for JSON communications, based upon the Fetch API","archived":false,"fork":false,"pushed_at":"2024-05-13T09:46:30.000Z","size":301,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-02T01:34:40.730Z","etag":null,"topics":["fetch-api","fetchjson","hacktoberfest","javascript","javascript-library","json-client","promise"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Voltra.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-03T14:12:49.000Z","updated_at":"2022-06-07T11:25:38.000Z","dependencies_parsed_at":"2024-11-15T17:39:10.996Z","dependency_job_id":"4d142c05-b7fe-4e27-b1f8-c1032df54d54","html_url":"https://github.com/Voltra/jsonclient","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voltra%2Fjsonclient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voltra%2Fjsonclient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voltra%2Fjsonclient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Voltra%2Fjsonclient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Voltra","download_url":"https://codeload.github.com/Voltra/jsonclient/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242076038,"owners_count":20068231,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fetch-api","fetchjson","hacktoberfest","javascript","javascript-library","json-client","promise"],"created_at":"2024-11-15T17:39:06.207Z","updated_at":"2026-06-10T07:31:19.788Z","avatar_url":"https://github.com/Voltra.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"logo.png\" alt=\"logo\" width=\"300\"\u003e\u003c/p\u003e\n\n# JsonClient\n\nJsonClient is a JavaScript HTTP client specialized for JSON communications, based upon the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).\n\nTherefore it is completely Promise based and makes it easy to communicate JSON data across your application.\n\n## How to ?\n\nFirst you need to get this library, either by using [npm (w/ node)](https://nodejs.org/en/) and `npm i --save @voltra/json` or by downloading it from the [GitHub repository](https://github.com/Voltra/jsonclient).\n\n\n\nThen you will need to use it in your application :\n\n* \\\u003e= ES6 : `import { $json } from \"@voltra/json\"`\n* Node (\u003cES6) : `const { $json } = require(\"@voltra/json\")`\n* In your HTML files : `\u003cscript src=\"your/path/to/dist/jsonclient.js\"\u003e\u003c/script\u003e` (exposes the variable `jsonclient` which contains the exports)\n\n\n\n### Exposed variables\n\nThe global export of library now exposes :\n\n```javascript\n{\n    $json, // default client\n    JsonClient, // client class\n    Middlewares, // class that stores middleware stacks for every hook\n    MiddlewareStack, // class that stores middlewares\n    middlewares, // a bunch of middleware installing functions\n}\n```\n\n\n\n### GET requests\n\nTherefore, the behavior of `$json.get` is very similar to the behavior of [`fetchJSON`]([fetchJSON](https://www.npmjs.com/package/fetch_json)).\n\n\n\n`$json.get :: (url: string, data: object|undefined) -\u003e Promise`\n\nThe Promise returned by `$json.get` resolves to the JSON data requested.\n\n\n\n### POST requests\n\nIf you have made any POST request via the Fetch API, you probably noticed that it is very redundant.\n\nTherefore, this library enables you to ease your job at emitting POST requests.\n\n\n\n`$json.post :: (url: string, data: object|undefined) -\u003e Promise`\n\n`$json.post :: (url: string, data: object|undefined, options: object) -\u003e Promise`\n\n```\n$json.post :: (\n\turl: string,\n\tdata: object|undefined,\n\tcache: JsonClient.enums.Cache,\n\tcredentials: JsonClient.enums.Credentials,\n\tmode: JsonClient.enums.Mode,\n\tredirect: JsonClient.enums.Redirect,\n\treferrer: JsonClient.enums.Referrer\n) -\u003e Promise\n```\n\n\n\n### PUT/DELETE/PATCH requests\n\nAll of these follow the same syntax as `$json.post` (PUT is `$json.put`, etc.).\n\n\n\nIf you have any doubts, you could refer to [Mozilla's guide on how to provide options to `fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Supplying_request_options) or ask for advices on my [Discord server](https://discord.gg/JtWAjbw).\n\n## Hooks and defaults\n\nThere are a few ways you can customize your JSON client (POST requests only) :\n\n* Pass your custom settings as the third argument\n* Change the default values\n* Use middlewares\n\n\n\n### Default values\n\nDefault values are located in the object `$json.defaults` and are classified per HTTP methods (only those supported).\n\nFor instance `$json.defaults.GET` are the default values for GET requests. There is also `$json.defaults.globals` that are applied for every method.\n\nNote that the order of application is :\n\n1. `defaults.globals`\n2. `defaults[METHOD]`\n3. your custom options\n\n\n\n### Middlewares\n\nThis library now exposes a middleware system with several hooks :\n\n1. `beforeRequest` which preprocesses data in order to process the request\n2. `beforeResponse` which preprocesses raw response data\n3. `afterResponse` which preprocesses (supposedly) preprocessed JSON data before passing it as the result of the Promise\n4. `afterError` which preprocesses the error before it is rethrown\n\nThe middleware stacks are exposed under `$json.middlewares[METHOD]` (i.e. for GET requests, it is under `$json.middlewares.GET`). You can therefore `pipe` your custom middlewares :\n\n```javascript\n// For instance\n$json.middlewares.GET.beforeRequest\n    .pipe(doStuff)\n    .pipe(thenDoSthg);\n```\n\n#### Default behavior (i.e. default middlewares)\n\nBy default, the `$json` is configured with enough middlewares so that\n\n```javascript\n$json.get(\"/api/book\", {\n    sort: \"author\",\n    order: \"asc\",\n    count: 69\n}).then(console.log)\n.catch(console.error);\n```\n\nWill emit a GET request to `/api/book?sort=author\u0026order=asc\u0026count=69` and log the resulting JSON whether it is the list of books or the error JSON.\n\n\n\n```javascript\n$json.post(\"/api/book\", {\n    author_id: 420,\n    name: \"Call of Cthulhu\",\n    description: \"Some lovecraftian masterpiece\"\n}).then(console.log)\n.catch(console.error);\n```\n\nWill emit a POST request to `/api/book` with a JSON body that contains the given data and log the resulting JSON whether it is the inserted book or the error JSON.\n\n\n\nNote that if the response itself is not JSON, it will emit the following JSON as error :\n\n```javascript\n{\n    error, // the raw error\n    response, // the raw response\n}\n```\n\n\n\n#### Default middlewares\n\nYou can find every single default middleware under the globally exported `middlewares` :\n\n```javascript\nconst { middlewares } = window.jsonclient;\n// OR\nconst { middlewares } = require(\"@voltra/json\");\n```\n\nThey are not really middlewares but rather functions that register the middleware on the `JsonClient` that you pass as parameter.\n\n#### Middleware hooks\n\n`beforeRequest` is a middleware stack of `JsonClientRequest` middlewares :\n\n```javascript\nconst myMiddleware = ({ path, data, options }) =\u003e {\n    // [...]\n    return {\n        path: myPath,\n        data: myData,\n        options: myOptions,\n    };\n    // the return value could be a promise\n    /// Note that the last middleware may only return `path` and `options`\n    /// Both being values such that `fetch(path, options)` is a valid call\n};\n```\n\n`beforeResponse` is a middleware stack of `Response` (as in `GlobalFetch.Response`) :\n\n```javascript\nconst myMiddleware = response =\u003e {\n    // [...]\n    return myResponse;\n    // the return value could be a promise\n};\n```\n\n`afterResponse` is a middleware stack of JSON data (or any javascript data) :\n\n```javascript\nconst myMiddleware = parsedJson =\u003e {\n    // [...]\n    return someParsedJson;\n    // the return value could be a promise\n};\n```\n\n`afterError` is a middleware stack of JSON data (or any javascript data) or `Error` objects :\n\n```javascript\nconst myMiddleware = error =\u003e {\n    // [...]\n    return myError;\n    // the return value could be a promise (that resolves to an error)\n};\n```\n\n\n\n#### Middleware stacks\n\nA middleware stack (i.e. `MiddlewareStack` instance) has several handy methods :\n\n* `pipe` which accepts a middleware (can be chained)\n* `execute` which accept data as input and processes the middleware stack over the data and results in a Promise\n* `at` which accepts an index and return the middleware at the given index (or `null` if there were none)\n* `removeAt` which accepts an index and removes the middleware at the given index, this will mutate the internal data structure so indexes may change (can be chained)\n\nYou can create an empty `MiddlewareStack` by calling `MiddlewareStack.empty()`.\n\n#### `Middlewares` the hub of middleware stacks\n\nOf course you can access each individual `MiddlewareStack` by its name (e.g. `$json.middlewares.GET.beforeRequest`) but you can also use helper methods directly from the `Middlewares` instance :\n\n```javascript\n$json.middlewares.GET.beforeRequest.pipe(myMiddleware);\n// is (almost) equivalent to\n$json.middlewares.GET.pipeBeforeRequest(myMiddleware);\n\n\n// You can chain helper calls\n$json.middlewares.GET\n\t.pipeBeforeRequest(myBeforeRequest)\n\t.pipeBeforeResponse(myBeforeResponse)\n\t.pipeAfterResponse(myAfterResponse)\n\t.pipeAfterError(myAfterError)\n\t// [...]\n```\n\n\n\n\n\n\n\n## Dependencies\n\nThere is only two dependencies :\n* `sequency` which is used internally to process arrays of data more efficiently (you don't have to do anything about it)\n\n* The Fetch API or `fetch` : As part of the Fetch API, `fetch` allows to emit HTTP requests. This library is heavily based around this function and therefore requires it, modern browsers implement it but there are also a lot of polyfills out there, here are two of them :\n\n  * [fetch-ponyfill](https://www.npmjs.com/package/fetch-ponyfill) : Works for both browser and Node :\n\n    ```javascript\n    const {fetch, Request, Response, Headers} = require(\"fetch-ponyfill\")();\n    global.fetch = fetch; //For Node, this.fetch = fetch for browser\n  \n    ///OR\n  \n    import fetchPonyfill from \"fetch-ponyfill\"\n    const { fetch, Request, Response, Headers } = fetchPonyfill();\n    global.fetch = fetch\n    ```\n  ```\n  \n  \n  ```\n  \n* [whatwg-fetch](https://www.npmjs.com/package/whatwg-fetch) : For old browsers\n  \n  * [node-fetch](https://www.npmjs.com/package/node-fetch) : For Node-based environments\n\n\n\n## Changes\n\n### v3.0.0\n\nDropping :\n\n* dependency on `fetchJSON`\n* support for method overriding/spoofing (no more `$json.method`)\n\n\n\nGlobally exposed variable for the browser is now `jsonclient` (i.e. `window.$json` =\u003e `window.jsonclient.$json`).\n\nNow exposing a middleware system under `$json.middlewares`.\n\nMoved `$json.enums` to be a static property of `JsonClient`, i.e. `JsonClient.enums`.\n\n### v2.1.0\n\nUpdated `fetchJSON` to use its latest version (v2.2.0)\n\n### v2.0.0\n\nRenamed `$json.postOptionsEnums` to `$json.enums`. \n\nAdded support for `PUT`, `DELETE` and `PATCH` methods (`$json.put`, `$json.delete` and `$json.patch` have the same signature as `$json.post`).\n\nAdded support for method override via `$json.method`, it follows the same signature as `$json.post` but adds the first parameter `method` which designate the HTTP method to override. It exposes `X-HTTP-Method-Override`, `X-Method-Override` and `X-HTTP-Method` headers with the provided values. It also exposes default bound versions (`$json.method.put`, `$json.method.delete` and `$json.method.patch`) that have the same signature as `$json.post`. \n\n### v1.3.0\n\nUpdated `fetchJSON` dependency to use its version `2.1.0` and provide defaults and customization to `$json.get`.\n\nUpdated `$json.post` to expose defaults for the `data` argument.\n\n\n\n## Troubleshooting\n\nIf you don't find an answer to your problem, feel free to ask for help on my [Discord server](https://discord.gg/JtWAjbw).\n\n\n\n**I can't use this library except by including it directly in the HTML**\n\n\u003e Until v1.1.0, there was an issue were the build process would simplify a conditional occuring in the UMD which would break the code for usage outside of the browser.\n\u003e\n\u003e This has been fixed in v1.1.0 by simply declaring the transpiled `build-babel/jsonclient.esm.js` file as the entry point of the application, thus making it available to use everywhere. As a sidenote, I'd like to point out that direct usage in the browser is done by including `dist/jsonclient.js` (which is not the entry point anymore).\n\u003e\n\u003e \n\u003e\n\u003e Make sure that the version of the library you have is at least 1.1.0 (check the `package.json` file), if not update it for the latest version.\n\u003e\n\u003e If you're still having this problem post v1.1.0, feel free to [open an issue on GitHub](https://github.com/Voltra/jsonclient/issues).\n\n\n\n**I cannot find `$json.postOptions`, where are they ?**\n\n\u003e Since v1.1.0, `$json.postOptions` has been renamed `$json.postOptionsEnums` in order to avoid any kind of confusion.\n\n\n\n**I am unable to get the requested data, there is an error in the console : `\"Something went wrong during data inspection (data is not JSON or couldn't reach file)\"`**\n\n\u003e This can mean two things (as said in the error message) :\n\u003e\n\u003e - The data is not **explicitely** marked as json (needs the`content-type` to be `application/json`, which is the standard way of identifying JSON)\n\u003e - The client was unable to reach the requested data (typo, wrong URL/URI, etc...)\n\n\n\n**I cannot use a callback for `$json.get` anymore, what's going on ?**\n\n\u003e That's very simple. Since v1.2.0 I have updated `fetch_json` to its version 2.0.0 (or latest). The callback has been replaced by an object that will be transformed into the query string (optional).\n\u003e\n\u003e I thought that since you can `then` you way out of it, the callback was completely unnecessary and has therefore been removed.\n\u003e\n\u003e But no you can enjoy an easy query string.\n\n\n\n**My server doesn't mark explicitely my data as JSON but it still lands properly, why ?**\n\n\u003e Again, since v1.2.0 I have updated `fetch_json` to its version 2.0.0 (or latest). It has loosen up the way it handles JSON conversion.\n\n\n\n---\n\nJoin the [Discord server](https://discord.gg/JtWAjbw) to talk about my libraries and get help if you need any.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoltra%2Fjsonclient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoltra%2Fjsonclient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoltra%2Fjsonclient/lists"}