Skip to content

Commit f7c9f86

Browse files
committed
docs(HOW_IT_WORKS): initial version
1 parent d21d25d commit f7c9f86

File tree

3 files changed

+126
-0
lines changed

3 files changed

+126
-0
lines changed

HOW_IT_WORKS.md

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
[back to `@octokit/rest`](.)
2+
3+
# How it works
4+
5+
![lifecycle](assets/lifecycle.png)
6+
7+
<!-- ①②③④⑤⑥⑦⑧⑨⑩ -->
8+
9+
1. [Endpoint options ① - ④](#endpoint-options)
10+
2. [Transform endpoint to request options ⑥ - ⑦](#transform)
11+
3. [Sending a request & receiving a response ⑧ & ⑩](#request)
12+
4. [Hooks ⑤ & ⑨](#request)
13+
14+
<a name="endpoint-options"></a>
15+
## Endpoint options (① - ④)
16+
17+
`@octokit/rest` exposes a method for each [REST API endpoint](https://developer.github.com/v3/), for example `github.repos.getForOrg()` for [`GET /orgs/:org/repos`](https://developer.github.com/v3/repos/#list-organization-repositories). The methods are generated from the [lib/routes.json](lib/routes.json) file which defines the **② endpoint default options** `method`, `url` and in some cases `headers`.
18+
19+
**② endpoint default options** are merged with **① global defaults**, which are based on [lib/endpoint/defaults.js](lib/endpoint/defaults.js) and the options that were passed into the `require('@octokit/rest')(options)` client setup.
20+
21+
Both are merged with **③ user options** passed into the method. Altogether they result in **④ endpoint options**.
22+
23+
**Example**: get all public repositories of the the [@octokit GitHub organization](https://github.com/octokit).
24+
25+
```js
26+
github.repos.getForOrg({org: 'octokit', type: 'public'})
27+
```
28+
29+
**④ endpoint options** will be
30+
31+
<table>
32+
<thead>
33+
<tr>
34+
<th>Option</th>
35+
<th>Value</th>
36+
<th>Source</th>
37+
</tr>
38+
</thead>
39+
<tr>
40+
<td><strong>baseUrl</strong></td>
41+
<td><code>'https://api.github.com'</code></td>
42+
<td>① endpoint defaults</td>
43+
</tr>
44+
<tr>
45+
<td><strong>user-agent</strong> <em>(header)</em></td>
46+
<td><code>'octokit/rest.js v1.0.0'</code></td>
47+
<td>① global defaults</td>
48+
</tr>
49+
<tr>
50+
<td><strong>accept</strong> <em>(header)</em></td>
51+
<td><code>'application/vnd.github.v3+json'</code></td>
52+
<td>① global defaults</td>
53+
</tr>
54+
<tr>
55+
<td><strong>method</strong></td>
56+
<td><code>'GET'</code></td>
57+
<td>② endpoint defaults</td>
58+
</tr>
59+
<tr>
60+
<td><strong>url</strong></td>
61+
<td><code>'/orgs/:org/repos'</code></td>
62+
<td>② endpoint defaults</td>
63+
</tr>
64+
<tr>
65+
<td><strong>org</strong> <em>(URL variable)</em></td>
66+
<td><code>'octokit'</code></td>
67+
<td>③ user options</td>
68+
</tr>
69+
<tr>
70+
<td><strong>type</strong> <em>(endpoint parameter)</em></td>
71+
<td><code>'public'</code></td>
72+
<td>③ user options</td>
73+
</tr>
74+
</table>
75+
76+
<a name="transform"></a>
77+
## Transform endpoint to request options (⑥ - ⑦)
78+
79+
**④ Endpoint options** are **⑥ transformed** into **⑦ request options**. Most of the transform is happening in [lib/endpoint/index.js](lib/endpoint/index.js).
80+
81+
For example, the endpoint options shown above would result in
82+
83+
<table>
84+
<tr>
85+
<th align=left>method</th>
86+
<td><code>'GET'</code></td>
87+
</tr>
88+
<tr>
89+
<th align=left>url</th>
90+
<td> <code>'https://api.github.com/orgs/octokit/repos?type=public'</code></td>
91+
</tr>
92+
<tr>
93+
<th align=left>headers[user-agent]</th>
94+
<td> <code>'octokit/rest.js v1.0.0'</code></td>
95+
</tr>
96+
</tr>
97+
<tr>
98+
<th align=left>headers[accept]</th>
99+
<td> <code>'application/vnd.github.v3+json'</code></td>
100+
</tr>
101+
</table>
102+
103+
<a name="request"></a>
104+
## Sending a request & receiving a response ⑧ & ⑩
105+
106+
Using **⑦ request options** a **⑧ request** is sent to the GitHub REST API. The **⑩ response** is returned to the user.
107+
108+
Most of the request/response is happening in [lib/request/request.js](lib/request/request.js). It is currently using Node’s native [http](https://nodejs.org/api/http.html) & [https](https://nodejs.org/api/https.html) modules, but we will probably use a fetch polyfill in future for better browser compatibility & smaller bundle size.
109+
110+
<a name="hooks"></a>
111+
## Hooks ⑤ & ⑨
112+
113+
Hooks are used internally to inject functionality like authentication. For example, the internal [authentication plugin](lib/plugins/authentication) is registering a request hook in [lib/plugins/authentication/index.js](lib/plugins/authentication/index.js). The method sets the `authorization` header based on authentication previously set using `github.authenticate()` before the **⑧ request**.
114+
115+
Hooks will be used in future for request pagination, throttling and handling of rate limits.
116+
117+
Hooks can be registered using `github.hook.{before|after}`:
118+
119+
```js
120+
github.hook.before('request', (options) => {})
121+
github.hook.after('request', (response, options) => {})
122+
```
123+
124+
The callbacks can return a Promise for asynchronous execution. `options` can be changed in the `github.hook.before` callback before they are transformed **⑥ transformed**. The **⑩ response** can be changed in the `github.hook.after` callback before it is returned to the user.
125+
126+
⚠️ The API is currently experimental and can change at any time.

assets/lifecycle.png

104 KB
Loading

assets/lifecycle.sketch

187 KB
Binary file not shown.

0 commit comments

Comments
 (0)