This repository has been archived by the owner on Sep 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added tutorials, or cookbook recipe's
- Loading branch information
Showing
2 changed files
with
209 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
# MetroJS Tutorial | ||
|
||
## Getting Started | ||
|
||
MetroJS is available as a NPM package: | ||
|
||
```shell | ||
npm install @muze-nl/metro | ||
``` | ||
|
||
Then use it like this: | ||
```javascript | ||
import * as metro from '@muze-nl/metro' | ||
``` | ||
|
||
Or you can use a CDN (Content Delivery Network), like this: | ||
```javascript | ||
import * as metro from 'https://cdn.jsdelivr.net/npm/@muze-nl/metro/src/metro.mjs' | ||
``` | ||
|
||
Or as a script tag: | ||
```html | ||
<script src="https://cdn.jsdelivr.net/npm/@muze-nl/metro/dist/browser.js"></script> | ||
``` | ||
|
||
The rest of this document assumes the functions provided by MetroJS will be available as `metro.*`. | ||
|
||
MetroJS is built on top of the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API), which is standard in all modern web browsers and in Node from version 18. If you are not familiar with this API, it is recommended to read the mdn documentation linked here first. | ||
|
||
## Fetching a public resource | ||
|
||
```javascript | ||
const client = metro.client('https://example.com') | ||
async function getData() { | ||
const response = await client.get('/resource') | ||
|
||
if (response.ok) { | ||
return response.text() | ||
} else { | ||
throw new NetworkError(response.status+': '+response.statusText) | ||
} | ||
} | ||
``` | ||
|
||
The main difference with the Fetch API here is that there is a `metro.client` object, which can be re-used for multiple requests. It also allows you to set default options for subsequent requests. | ||
|
||
In addition, the single `fetch()` function is replaced with seperate functions for each HTTP method. In this case `get()`. | ||
|
||
## POSTing to a public resource | ||
|
||
```javascript | ||
const client = metro.client('https://example.com') | ||
|
||
async function postData(data) { | ||
const response = await client.post('/resource', metro.formdata(data)) | ||
if (response.ok) { | ||
return response.text() | ||
} else { | ||
throw new NetworkError(response.status+': '+response.statusText) | ||
} | ||
} | ||
``` | ||
|
||
A FormData object is automatically assigned to the Request.body, but you can also do this explicitly: | ||
|
||
```javascript | ||
const client = metro.client('https://example.com') | ||
|
||
async function postData(data) { | ||
const response = await client.post('/resource', { | ||
body: metro.formdata(data) | ||
}) | ||
if (response.ok) { | ||
return response.text() | ||
} else { | ||
throw new NetworkError(response.status+': '+response.statusText) | ||
} | ||
} | ||
``` | ||
|
||
## Adding Accept Header | ||
|
||
As default: | ||
|
||
```javascript | ||
const client = metro.client('https://example.com', { | ||
headers: { | ||
Accept: 'application/json' | ||
} | ||
}) | ||
``` | ||
|
||
Or for a specific request: | ||
|
||
```javascript | ||
async function postData(data) { | ||
const response = await client.post('/resource', metro.formdata(data), { | ||
headers: { | ||
Accept: 'application/json' | ||
} | ||
}) | ||
if (response.ok) { | ||
return response.json() | ||
} else { | ||
throw new NetworkError(response.status+': '+response.statusText) | ||
} | ||
} | ||
``` | ||
|
||
## POSTing with a JSON body | ||
|
||
```javascript | ||
const client = metro.client('https://example.com') | ||
|
||
async function postData(data) { | ||
const response = await client.post('/resource', { | ||
body: data, | ||
headers: { | ||
Accept: 'application/json', | ||
'Content-Type': 'application/json' | ||
} | ||
}) | ||
if (response.ok) { | ||
return response.json() | ||
} else { | ||
throw new NetworkError(response.status+': '+response.statusText) | ||
} | ||
} | ||
``` | ||
|
||
## JSON middleware | ||
|
||
```javascript | ||
import jsonmw from '@muze-nl/metro/src/mw/json.mjs' | ||
|
||
const client = metro.client('https://example.com').with( jsonmw() ) | ||
|
||
async function postData(data) { | ||
const response = await client.post('/resource', { | ||
body: data | ||
}) | ||
if (response.ok) { | ||
return response.body | ||
} else { | ||
throw new NetworkError(response.status+': '+response.statusText) | ||
} | ||
} | ||
``` | ||
|
||
## CORS Requests | ||
|
||
Just like Fetch, Metro automatically uses CORS mode if you send a request to a different domain. But if you need more than basic CORS, you can use all the options available in the [Fetch API](): | ||
|
||
```javascript | ||
const client = metro.client('https://example.com') | ||
|
||
async function corsPostData(data) { | ||
const response = await client.post('/resource', { | ||
body: metro.formdata(data), | ||
mode: 'cors', | ||
credentials: 'same-origin' | ||
}) | ||
if (response.ok) { | ||
return response.text() | ||
} else { | ||
throw new NetworkError(response.status+': '+response.statusText) | ||
} | ||
} | ||
``` | ||
|
||
## Basic Authorization | ||
|
||
If you allow the browser to show a prompt for the user to login with a username and password, then there is no difference in code between a request with or without Basic Authorization: | ||
|
||
```javascript | ||
const client = metro.client('https://example.com') | ||
|
||
async function getPrivateData(data) { | ||
const response = await client.get('/private') | ||
if (response.ok) { | ||
return response.text() | ||
} else { | ||
throw new NetworkError(response.status+': '+response.statusText) | ||
} | ||
} | ||
``` | ||
|
||
But if you want to avoid that prompt, and know the username and password, you can add the authentication header yourself, like this: | ||
|
||
```javascript | ||
const user = 'Foo' | ||
const pass = 'Bar' | ||
const client = metro.client('https://example.com', { | ||
headers: { | ||
Authorization: 'Basic '+btoa(user+':'+pass) | ||
} | ||
} | ||
```` | ||
|
||
## Adding Bearer Token | ||
|
||
```javascript | ||
const token = 'Foo' | ||
const client = metro.client('https://example.com', { | ||
headers: { | ||
Authorization: 'Bearer '+token | ||
} | ||
} | ||
```` |