You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: content/4.resources/1.learn/1.ofetch-101-first-hand.md
+89-44
Original file line number
Diff line number
Diff line change
@@ -12,15 +12,13 @@ modifiedAt: 2023-09-04
12
12
layout: learn-post
13
13
---
14
14
15
-
## Introduction
15
+
[`ofetch`](https://github.com/unjs/ofetch) is a utility package to make HTTP requests. It exists to unify the API between node, browser and workers and is build on top of the [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
16
16
17
-
`ofetch` is a utility package to make HTTP requests. It exists to unify the API between node, browser and workers.
18
-
19
-
In fact, Node.js has it's [own fetch](https://undici.nodejs.org/#/) since version 17.5.0 under an experimental flag and [full support at version 18](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API#browser_compatibility). If we want to support order version, we will need to use a third party package.
17
+
In fact, Node.js [full support the fetch API since version 18](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API#browser_compatibility) via the [unidici project](https://github.com/nodejs/undici). If we want to support older version, we will need to use a third party package.
20
18
21
19
In the same time, we want to be able to fetch in every environment with the same code. Code could start running in a worker and then in a browser.
22
20
23
-
`ofetch` have been created to simplify these tasks and provide a wrapper around the native fetch API with more options and features.
21
+
[`ofetch`](https://github.com/unjs/ofetch) have been created to simplify these tasks and provide a wrapper around the native fetch API with more options and features.
24
22
25
23
<!-- TODO: add links to /packages/ofetch and to examples (create a component like https://github.com/Barbapapazes/esteban-soubiran.site/blob/main/components/content/GitHubLink.vue -->
26
24
@@ -42,30 +40,24 @@ Then, install the package:
42
40
npm install ofetch
43
41
```
44
42
45
-
To easily run TypeScript scripts, we can install [jiti](/packages/jiti) as a dev dependency:
46
-
47
-
```bash
48
-
npm install -D jiti
49
-
```
50
-
51
-
<!-- TODO: add link to jiti 101 article -->
43
+
::alert{type="info"}
44
+
We can use the package manager of our choice like `npm`, `yarn`, `pnpm` or `bun`.
45
+
::
52
46
53
47
## First request
54
48
55
-
In order to make our first request, let's create a file named `first-request.ts` with the following content:
56
-
57
-
```ts [first-request.ts]
58
-
import { $fetch } from'ofetch'
49
+
In order to make our first request, let's create a file named `first-request.mjs` with the following content:
59
50
60
-
asyncfunction main() {}
51
+
```ts [first-request.mjs]
52
+
import { ofetch } from'ofetch'
61
53
62
-
main().catch(console.error) // Useful to catch errors
54
+
const data =awaitofetch('https://ungh.cc/repos/unjs/ofetch')
63
55
```
64
56
65
57
Then, we can run the script with:
66
58
67
59
```bash
68
-
jiti first-request.ts
60
+
node first-request.mjs
69
61
```
70
62
71
63
And _voilà_, we should see something like this:
@@ -88,17 +80,70 @@ And _voilà_, we should see something like this:
88
80
}
89
81
```
90
82
91
-
We have made our first request with ofetch! :tada: Easy, right?
83
+
We have made our first request with [`ofetch`](https://github.com/unjs/ofetch)! :tada: Easy, right?
92
84
93
85
### Manual parsing
94
86
95
-
<!-- explain the automatic parsing with destr and the fact that you can then control it -->
87
+
In our first example, the result return is automatically parsed to JSON thanks to [`unjs/destr`](https://github.com/unjs/destr).
88
+
89
+
<!-- TODO: add related article to 101 destr -->
90
+
91
+
This behavior is very useful but sometimes, we want to manually parse the result.
92
+
93
+
The first way to change how received data is parsed is using the `responseType` option. [`ofetch`](https://github.com/unjs/ofetch) provides several options:
94
+
95
+
-`text` to have the raw text
96
+
-`json` to have a JSON object
97
+
-`blob` to have a `Blob` object
98
+
-`arrayBuffer` to have an `ArrayBuffer` object
99
+
-`stream` to have a `ReadableStream` object
100
+
To try it, let's create a new file named `manual-parsing.mjs`.
101
+
102
+
```ts [manual-parsing.mjs]
103
+
import { ofetch } from'ofetch'
104
+
105
+
const data =awaitofetch('https://ungh.cc/repos/unjs/ofetch', {
106
+
responseType: 'blob',
107
+
})
108
+
109
+
console.log(data) // A blob object is returned.
110
+
```
111
+
112
+
We can also provide a custom function to parse the result using the `parseFunction` option. By default [`ofetch`](https://github.com/unjs/ofetch) use [`unjs/destr`](https://github.com/unjs/destr). Let's make our custom parser by creating a new file named `custom-parsing.mjs`.
113
+
114
+
```ts [custom-parsing.mjs]
115
+
import { ofetch } from'ofetch'
116
+
117
+
const data =awaitofetch('https://ungh.cc/repos/unjs/ofetch', {
118
+
parseFunction: (data) => {
119
+
returndata// We return the raw data but we could use JSON.parse to return a JSON object.
120
+
},
121
+
})
122
+
123
+
console.log(data) // The data is not parsed.
124
+
```
125
+
126
+
The function take the raw data as argument and must return something, ideally, data parsed.
96
127
97
128
## Type safety
98
129
99
-
Thanks to TypeScript and generics, ofetch can be type safe. Let's see how to do it.
130
+
Thanks to TypeScript and generics, [`ofetch`](https://github.com/unjs/ofetch) can be type safe. In order to easily use TypeScript to run our scripts, we will use [`unjs/jiti`](https://github.com/unjs/jiti).
131
+
132
+
<!-- TODO: add related article to 101 jiti -->
133
+
134
+
We can install it globally with:
135
+
136
+
```bash
137
+
npm install -g jiti
138
+
```
139
+
140
+
Then, we can run our script with:
141
+
142
+
```bash
143
+
jiti <filename.ts>
144
+
```
100
145
101
-
First, let's create another file called `type-safety.ts`.
146
+
Now that we are ready, let's create another file called `type-safety.ts` to type safe our [`ofetch`](https://github.com/unjs/ofetch) request:
102
147
103
148
```bash
104
149
touch type-safety.ts
@@ -116,10 +161,10 @@ interface Repo {
116
161
}
117
162
```
118
163
119
-
Now, we can use the `$fetch` function, like in our `first-request.ts` file, but this time, we will add a generic type to it.
164
+
Now, we can use the [`ofetch`](https://github.com/unjs/ofetch) function, like in our `first-request.ts` file, but this time, we will add a generic type to it.
console.log(`The repo ${repo.name} has ${repo.stars} stars.`) // The repo object is now strongly typed.
136
181
}
@@ -146,17 +191,17 @@ This is **not a validation**. It's just a way to tell TypeScript what the respon
146
191
147
192
## Options
148
193
149
-
With `ofetch`, we can do much more than simple `GET` requests. Let's see how to use and combine options to make more complex requests.
194
+
With [`ofetch`](https://github.com/unjs/ofetch), we can do much more than simple `GET` requests. Let's see how to use and combine options to make more complex requests.
150
195
151
196
### Methods
152
197
153
-
`ofetch` supports all the HTTP methods. Let's see how to use one of them. To test a `POST` request, we will use the GitHub API. Let's create a new file named `methods.ts` with the following content:
198
+
[`ofetch`](https://github.com/unjs/ofetch) supports all the HTTP methods. Let's see how to use one of them. To test a `POST` request, we will use the GitHub API. Let's create a new file named `methods.ts` with the following content:
Of course, when the method is not `GET` or `HEAD`, we can provide a body to the request. Let's see how to do it by creating a new file named `body.ts` with the following content:
// To provide a body, we need to use the `body` option and just use an object.
192
237
body: {
@@ -223,13 +268,13 @@ The body can take several formats:
223
268
224
269
We can also provide some query string parameters to the request. They can be useful to add filters or to paginate the results.
225
270
226
-
Imagine we want to get the last 2 tags of the `unjs/ofetch` repository. We can do it by creating a new file named `query-string.ts` with the following content:
271
+
Imagine we want to get the last 2 tags of the [`unjs/ofetch`](https://github.com/unjs/ofetch) repository. We can do it by creating a new file named `query-string.ts` with the following content:
@@ -279,10 +324,10 @@ We can find a key `params` in the options. It's an alias for `query`.
279
324
In the [`methods` section](#methods), we encountered an error because we didn't provide any authentication. With headers, we can solve our problem. In fact, we need to provide to GitHub an authentication token in an header named `Authorization` with a value of `token <token>`. Let's see how to do it by creating a new file named `headers.ts` with the following content:
And that's a good thing! It means we have successfully authenticated to GitHub. We just need to provide a valid body to the request but now, we know how to do it! We have to add the `body` option to the request with correct data:
@@ -353,14 +398,14 @@ Never put credential token directly in code. Use an environment variable instead
353
398
354
399
### Error handling
355
400
356
-
This part is straight forward with `ofetch`. Surround the HTTP call with a `try/catch` block and we're done. Let's see how to do it by creating a new file named `error-handling.ts` with the following content:
401
+
This part is straight forward with [`ofetch`](https://github.com/unjs/ofetch). Surround the HTTP call with a `try/catch` block and we're done. Let's see how to do it by creating a new file named `error-handling.ts` with the following content:
357
402
358
403
```ts [error-handling.ts]
359
-
import { $fetch } from'ofetch'
404
+
import { ofetch } from'ofetch'
360
405
361
406
asyncfunction main() {
362
407
try {
363
-
await$fetch('https://api.github.com', {
408
+
awaitofetch('https://api.github.com', {
364
409
method: 'POST'// This allow us to get an error.
365
410
})
366
411
}
@@ -402,6 +447,6 @@ We can also completely disable error response using option `ignoreResponseError`
402
447
403
448
## Conclusion
404
449
405
-
We have seen how to use `ofetch` to easily make HTTP requests in any environment. We have seen how to use the different options to make more complex requests and how to gracefully handle errors.
450
+
We have seen how to use [`ofetch`](https://github.com/unjs/ofetch) to easily make HTTP requests in any environment. We have seen how to use the different options to make more complex requests and how to gracefully handle errors.
406
451
407
-
With this 101, we've just scratch the surface of `ofetch`. In next articles, we will use some advanced options like `retry` and `timeout` to make our requests more robust, interceptors to make optimistic updates and how to create a fetch with some default options!
452
+
With this 101, we've just scratch the surface of [`ofetch`](https://github.com/unjs/ofetch). In next articles, we will use some advanced options like `retry` and `timeout` to make our requests more robust, interceptors to make optimistic updates and how to create a fetch with some default options!
0 commit comments