|
| 1 | +# request.js |
| 2 | + |
| 3 | +> Send parameterized requests to GitHub’s APIs with sensible defaults in browsers and Node |
| 4 | +
|
| 5 | +`@octokit/request` is a request library for browsers & node that makes it easier |
| 6 | +to interact with [GitHub’s REST API](https://developer.github.com/v3/) and |
| 7 | +[GitHub’s GraphQL API](https://developer.github.com/v4/guides/forming-calls/#the-graphql-endpoint). |
| 8 | + |
| 9 | +It uses [`@octokit/endpoint`](https://github.com/octokit/endpoint.js) to parse |
| 10 | +the passed options and sends the request using [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) |
| 11 | + ([node-fetch](https://github.com/bitinn/node-fetch) in Node). |
| 12 | + |
| 13 | +## Usage |
| 14 | + |
| 15 | +### Node |
| 16 | + |
| 17 | +Install with `npm install @octokit/request`. |
| 18 | + |
| 19 | +```js |
| 20 | +const octokitRequest = require('@octokit/request') |
| 21 | +``` |
| 22 | + |
| 23 | +### Browser |
| 24 | + |
| 25 | +1. Download `octokit-request.min.js` from the latest release: https://github.com/octokit/request.js/releases |
| 26 | + |
| 27 | +2. Load it as script into your web application: |
| 28 | + |
| 29 | + ```html |
| 30 | + <script src="request-rest.min.js"></script> |
| 31 | + ``` |
| 32 | + |
| 33 | +3. The `octokitRequest` is now available |
| 34 | + |
| 35 | +### REST API example |
| 36 | + |
| 37 | +```js |
| 38 | +// Following GitHub docs formatting: |
| 39 | +// https://developer.github.com/v3/repos/#list-organization-repositories |
| 40 | +const result = await octokitRequest('GET /orgs/:org/repos', { |
| 41 | + headers: { |
| 42 | + authorization: 'token 0000000000000000000000000000000000000001' |
| 43 | + }, |
| 44 | + org: 'octokit', |
| 45 | + type: 'private' |
| 46 | +}) |
| 47 | + |
| 48 | +console.log(`${result.data.length} repos found.`) |
| 49 | +``` |
| 50 | + |
| 51 | +### GraphQL example |
| 52 | + |
| 53 | +```js |
| 54 | +const result = await octokitRequest('POST /graphql', { |
| 55 | + headers: { |
| 56 | + authorization: 'token 0000000000000000000000000000000000000001' |
| 57 | + }, |
| 58 | + query: `query ($login: String!) { |
| 59 | + organization(login: $login) { |
| 60 | + repositories(privacy: PRIVATE) { |
| 61 | + totalCount |
| 62 | + } |
| 63 | + } |
| 64 | + }`, |
| 65 | + variables: { |
| 66 | + login: 'octokit' |
| 67 | + } |
| 68 | +}) |
| 69 | +``` |
| 70 | + |
| 71 | +### Alternative: pass `method` & `url` as part of options |
| 72 | + |
| 73 | +Alternatively, pass in a method and a url |
| 74 | + |
| 75 | +```js |
| 76 | +const result = await octokitRequest({ |
| 77 | + method: 'GET', |
| 78 | + url: '/orgs/:org/repos', |
| 79 | + headers: { |
| 80 | + authorization: 'token 0000000000000000000000000000000000000001' |
| 81 | + }, |
| 82 | + org: 'octokit', |
| 83 | + type: 'private' |
| 84 | +}) |
| 85 | +``` |
| 86 | + |
| 87 | +## Options |
| 88 | + |
| 89 | +<table> |
| 90 | + <thead> |
| 91 | + <tr> |
| 92 | + <th align=left> |
| 93 | + name |
| 94 | + </th> |
| 95 | + <th align=left> |
| 96 | + type |
| 97 | + </th> |
| 98 | + <th align=left> |
| 99 | + description |
| 100 | + </th> |
| 101 | + </tr> |
| 102 | + </thead> |
| 103 | + <tr> |
| 104 | + <th align=left> |
| 105 | + <code>baseUrl</code> |
| 106 | + </th> |
| 107 | + <td> |
| 108 | + String |
| 109 | + </td> |
| 110 | + <td> |
| 111 | + <strong>Required.</strong> Any supported <a href="https://developer.github.com/v3/#http-verbs">http verb</a>, case insensitive. <em>Defaults to <code>https://api.github.com</code></em>. |
| 112 | + </td> |
| 113 | + </tr> |
| 114 | + <th align=left> |
| 115 | + <code>headers</code> |
| 116 | + </th> |
| 117 | + <td> |
| 118 | + Object |
| 119 | + </td> |
| 120 | + <td> |
| 121 | + Custom headers. Passed headers are merged with defaults:<br> |
| 122 | + <em><code>headers['user-agent']</code> defaults to <code>octokit-rest.js/1.2.3</code> (where <code>1.2.3</code> is the released version)</em>.<br> |
| 123 | + <em><code>headers['accept']</code> defaults to <code>application/vnd.github.v3+json</code>.<br> |
| 124 | + </td> |
| 125 | + </tr> |
| 126 | + <tr> |
| 127 | + <th align=left> |
| 128 | + <code>method</code> |
| 129 | + </th> |
| 130 | + <td> |
| 131 | + String |
| 132 | + </td> |
| 133 | + <td> |
| 134 | + <strong>Required.</strong> Any supported <a href="https://developer.github.com/v3/#http-verbs">http verb</a>, case insensitive. <em>Defaults to <code>Get</code></em>. |
| 135 | + </td> |
| 136 | + </tr> |
| 137 | + <tr> |
| 138 | + <th align=left> |
| 139 | + <code>url</code> |
| 140 | + </th> |
| 141 | + <td> |
| 142 | + String |
| 143 | + </td> |
| 144 | + <td> |
| 145 | + <strong>Required.</strong> A path or full URL which may contain <code>:variable</code> or <code>{variable}</code> placeholders, |
| 146 | + e.g. <code>/orgs/:org/repos</code>. The <code>url</code> is parsed using <a href="https://github.com/bramstein/url-template">url-template</a>. |
| 147 | + </td> |
| 148 | + </tr> |
| 149 | + <tr> |
| 150 | + <th align=left> |
| 151 | + <code>url</code> |
| 152 | + </th> |
| 153 | + <td> |
| 154 | + String |
| 155 | + </td> |
| 156 | + <td> |
| 157 | + <strong>Required.</strong> A path or full URL which may contain <code>:variable</code> or <code>{variable}</code> placeholders, |
| 158 | + e.g. <code>/orgs/:org/repos</code>. The <code>url</code> is parsed using <a href="https://github.com/bramstein/url-template">url-template</a>. |
| 159 | + </td> |
| 160 | + </tr> |
| 161 | + <tr> |
| 162 | + <th align=left> |
| 163 | + <code>data</code> |
| 164 | + </th> |
| 165 | + <td> |
| 166 | + Any |
| 167 | + </td> |
| 168 | + <td> |
| 169 | + Set request body directly instead of setting it to JSON based on additional parameters. See <a href="#data-parameter">"The `data` parameter"</a> below. |
| 170 | + </td> |
| 171 | + </tr> |
| 172 | +</table> |
| 173 | + |
| 174 | +All other options will passed depending on the `method` and `url` options. |
| 175 | + |
| 176 | +1. If the option key is a placeholder in the `url`, it will be used as replacement. For example, if the passed options are `{url: '/orgs/:org/repos', org: 'foo'}` the returned `options.url` is `https://api.github.com/orgs/foo/repos` |
| 177 | +2. If the `method` is `GET` or `HEAD`, the option is passed as query parameter |
| 178 | +3. Otherwise the parameter is passed in the request body as JSON key. |
| 179 | + |
| 180 | +## Result |
| 181 | + |
| 182 | +`octokitRequest` returns a promise and resolves with 3 keys |
| 183 | + |
| 184 | +<table> |
| 185 | + <thead> |
| 186 | + <tr> |
| 187 | + <th align=left> |
| 188 | + key |
| 189 | + </th> |
| 190 | + <th align=left> |
| 191 | + type |
| 192 | + </th> |
| 193 | + <th align=left> |
| 194 | + description |
| 195 | + </th> |
| 196 | + </tr> |
| 197 | + </thead> |
| 198 | + <tr> |
| 199 | + <th align=left><code>headers</code></th> |
| 200 | + <td>Object</td> |
| 201 | + <td>All response headers</td> |
| 202 | + </tr> |
| 203 | + <tr> |
| 204 | + <th align=left><code>code</code></th> |
| 205 | + <td>Integer</td> |
| 206 | + <td>Response status code</td> |
| 207 | + </tr> |
| 208 | + <tr> |
| 209 | + <th align=left><code>redirect</code></th> |
| 210 | + <td>String</td> |
| 211 | + <td>Set to <code>"manual"</code> to extract redirect headers, <code>"error"</code> to reject redirect. Defaults to <code>"follow"</code></td> |
| 212 | + </tr> |
| 213 | + <tr> |
| 214 | + <th align=left><code>data</code></th> |
| 215 | + <td>Any</td> |
| 216 | + <td>The response body as returned from server. If the response is JSON then it will be parsed into an object</td> |
| 217 | + </tr> |
| 218 | + <tr> |
| 219 | + <th align=left><code>agent</code></th> |
| 220 | + <td>Node http(s).Agent</td> |
| 221 | + <td>For advanced request options in node you can pass in a node Agent (<a href="https://nodejs.org/api/http.html#http_class_http_agent">http</a>, <a href="https://nodejs.org/api/https.html#https_class_https_agent">https</a>)</td> |
| 222 | + </tr> |
| 223 | +</table> |
| 224 | + |
| 225 | +## `request.defaults()` |
| 226 | + |
| 227 | +Override or set default options. Example: |
| 228 | + |
| 229 | +```js |
| 230 | +const myOctokitRequest = require('@octokit/request').defaults({ |
| 231 | + baseUrl: 'http://github-enterprise.acme-inc.com/api/v3', |
| 232 | + headers: { |
| 233 | + 'user-agent': 'myApp/1.2.3', |
| 234 | + authorization: `token 0000000000000000000000000000000000000001` |
| 235 | + }, |
| 236 | + org: 'my-project', |
| 237 | + per_page: 100 |
| 238 | +}) |
| 239 | + |
| 240 | +myOctokitRequest(`GET /orgs/:org/repos`) |
| 241 | +``` |
| 242 | + |
| 243 | +You can call `.defaults()` again on the returned method, the defaults will cascade. |
| 244 | + |
| 245 | +```js |
| 246 | +const myProjectRequest = request.defaults({ |
| 247 | + baseUrl: 'http://github-enterprise.acme-inc.com/api/v3', |
| 248 | + headers: { |
| 249 | + 'user-agent': 'myApp/1.2.3' |
| 250 | + }, |
| 251 | + org: 'my-project' |
| 252 | +}) |
| 253 | +const myProjectRequestWithAuth = myProjectRequest.defaults({ |
| 254 | + headers: { |
| 255 | + authorization: `token 0000000000000000000000000000000000000001` |
| 256 | + } |
| 257 | +}) |
| 258 | +``` |
| 259 | + |
| 260 | +`myProjectRequest` now defaults the `baseUrl`, `headers['user-agent']`, |
| 261 | +`org` and `headers['authorization']` on top of `headers['accept']` that is set |
| 262 | +by the global default. |
| 263 | + |
| 264 | +## Special cases |
| 265 | + |
| 266 | +<a name="data-parameter"></a> |
| 267 | +### The `data` parameter – set request body directly |
| 268 | + |
| 269 | +Some endpoints such as [Render a Markdown document in raw mode](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode) don’t have parameters that are sent as request body keys, instead the request body needs to be set directly. In these cases, set the `data` parameter. |
| 270 | + |
| 271 | +```js |
| 272 | +const options = endpoint('POST /markdown/raw', { |
| 273 | + data: 'Hello world github/linguist#1 **cool**, and #1!', |
| 274 | + headers: { |
| 275 | + accept: 'text/html;charset=utf-8', |
| 276 | + 'content-type': 'text/plain' |
| 277 | + } |
| 278 | +}) |
| 279 | + |
| 280 | +// options is |
| 281 | +// { |
| 282 | +// method: 'post', |
| 283 | +// url: 'https://api.github.com/markdown/raw', |
| 284 | +// headers: { |
| 285 | +// accept: 'text/html;charset=utf-8', |
| 286 | +// 'content-type': 'text/plain', |
| 287 | +// 'user-agent': userAgent |
| 288 | +// }, |
| 289 | +// body: 'Hello world github/linguist#1 **cool**, and #1!' |
| 290 | +// } |
| 291 | +``` |
| 292 | + |
| 293 | +### Set parameters for both the URL/query and the request body |
| 294 | + |
| 295 | +There are API endpoints that accept both query parameters as well as a body. In that case you need to add the query parameters as templates to `options.url`, as defined in the [RFC 6570 URI Template specification](https://tools.ietf.org/html/rfc6570). |
| 296 | + |
| 297 | +Example |
| 298 | + |
| 299 | +```js |
| 300 | +octokitRequest('POST https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets{?name,label}', { |
| 301 | + name: 'example.zip', |
| 302 | + label: 'short description', |
| 303 | + headers: { |
| 304 | + 'content-type': 'text/plain', |
| 305 | + 'content-length': 14, |
| 306 | + authorization: `token 0000000000000000000000000000000000000001` |
| 307 | + }, |
| 308 | + data: 'Hello, world!' |
| 309 | +}) |
| 310 | +``` |
| 311 | + |
| 312 | + |
| 313 | + |
| 314 | +## LICENSE |
| 315 | + |
| 316 | +[MIT](LICENSE) |
0 commit comments