H1Intro to APIs
API (Application Programming Interface,应用程序编程接口) 是一组定义了应用程序如何与其他软件组件(包括操作系统、库、服务等)进行交互的协议和工具。通常情况下,API 用于通过定义和限制公共方法和属性的方式,向外界提供一组可以安全地使用的功能。
API 可以使得应用程序在不直接访问底层代码的情况下,使用其他程序或服务的功能,从而简化了应用程序的开发过程。例如,通过调用第三方公司的 API,你的应用程序可以获取天气信息、交通信息或其他数据,而不必自己编写这些功能的代码。
在 Web 开发中,API 通常是指一组可以让客户端通过网络请求访问的接口,例如 RESTful API 和 GraphQL API。Web API 通常会返回数据的格式可以是 JSON 或 XML 等,这些数据可以用于前端网站或移动应用程序的展示或其他用途。
H2Client
Any device that connects to the internet to get data from somewhere (makes a "request")
H2Server
Basically just a computer. Accepts requests from clients asking for something, then responds to the client with that thing (e.g. an HTML page, an image or file, or just plain data)
H2Requests
- When a device asks for a "resource" (data, image, HTML page, authentication token, etc.)
- Requires a connection to the internet somehow.
H2Responses
- The reply to the request.
- Could contain the resource (HTML, JSON data, etc.) asked for by the client.
H2Fetch API
Syntax:
js
fetch("url", { method: "POST", body })
.then((response) => response.json())
.then((data) => console.log(data));
method
:GET(默认)、POST、PUT、DELETE 等。第二个参数(可选):包括很多属性如:method、body、headers 等。
H1URLs & REST
H2HTML Requests
HTTP stands for Hypertext Transfer Protocol.(超文本传输协议)
A protocol is an agreed-upon(商定的), standard way of doing something.
HTTP is a protocol for determining how Hypertext (text) should be transferred over the internet.
H2Component of a Request
H3Path (URL)
- Full URL: https://api.example.com/posts
- Base URL: https://api.example.com
- Endpoint: /posts
H3Method
- GET: Getting data (默认方法)
- POST: Adding new data
- Like Blog POST or Facebook POST
- PUT: Updating existing data
- DELETE: Removing data
- Others (PATCH, OPTIONS, etc.)
H3Body
-
The data we want to send to the server.
-
Only makes sense with POST and PUT requests.
-
Needs to be turned into JSON first:
JSON.stringify()
js
fetch("https://api.example.com/posts", { method: "POST", body: JSON.stringify({ title: "My First Blog", completed: true, }), });
H3Headers
- Extra / meta information about the outgoing request.
- Auth, body info, client info, etc.
js
fetch("https://api.example.com/posts", {
method: "POST",
body: JSON.stringify({
title: "My First Blog",
completed: true,
}),
headers: {
"Content-Type": "application/json",
},
});
发送网络请求时需要设置请求头(headers),而如果请求头未正确设置,服务器就无法正确识别请求类型、请求数据格式等信息,从而请求失败,服务器甚至可能拒绝接收请求。如果请求头缺失,那么请求体中的数据将无法传输给服务器。
H2REST
REpresentational, State, Transfer
REST is a design pattern to provide a standard way for clients and servers to communicate.
RESTful 风格的设计,以博客为例:
- GET /articles(获取所有文章)查
- POST /articles(创建一篇新文章)增
- PUT /articles/1(更新 ID 为 1 的文章)改
- DELETE /articles/1(删除 ID 为 1 的文章)删
H2Query Strings
查询字符串
It's a way to filter results.
例如:<BaseURL>/name=harris&sex=male
H1Async JavaScript
H2Synchronous JavaScript
- Each command must complete before the next command can execute.
- No two commands can be running at the same time as each other.
H2"Asynchronous" JavaScript
Code that can run "out of order". It allows a lengthy operation to start but finishes at a later time without blocking other code from running in the meantime.
H2Promise
It has three states:
Pending: The promise has not yet to be completed
Fulfilled: The promise was completed as promised
Rejected: ≈
js
const promise = fetch(<URL>)
promise.then(function() {})
fetch 方法会返回一个 promise 对象
H2async & await
- async goes before the function.
- await goes before a method/function that returns a promise.
Original:
js
function handleClick() {
fetch("https://apis.scrimba.com/deckofcards/api/deck/new/shuffle/")
.then((res) => res.json())
.then((data) => {
remainingText.textContent = `Remaining cards: ${data.remaining}`;
deckId = data.deck_id;
console.log(deckId);
});
}
After:
js
async function handleClick() {
const res = await fetch(
"https://apis.scrimba.com/deckofcards/api/deck/new/shuffle/"
);
const data = await res.json();
remainingText.textContent = `Remaining cards: ${data.remaining}`;
deckId = data.deck_id;
console.log(deckId);
}
React:
jsx
const SomeComponent = () => {
const [list, setList] = useState([]);
useEffect(() => {
const fetchData = async () => {
const res = await fetch(
"https://apis.scrimba.com/deckofcards/api/deck/new/shuffle/"
);
const data = await res.json();
setList(data);
};
fetchData();
}, []);
return <>...</>;
};
H1Promise Rejection
H2catch()
js
fetch(<URL>)
.then(res => res.json())
.then(data => {
//...
}
.catch(err => {
// This is where we can handle the error
// console.error(err)
console.log("Something went wrong! 😭")
})
React:
jsx
const SomeComponent = () => {
const [list, setList] = useState([]);
useEffect(() => {
const fetchData = async () => {
try {
const res = await fetch(
"https://apis.scrimba.com/deckofcards/api/deck/new/shuffle/"
);
const data = await res.json();
setList(data);
} catch (error) {
console.error("Error fetching data:", error);
}
};
fetchData();
}, []);
return <>...</>;
};
H2Check for error responses
js
fetch(<URL>)
.then(res => {
if (!res.ok) {
// 重点
throw Error("Something went wrong")
}
console.log(res.status)
return res.json()
})
.then(data => {
console.log(data)
})
.catch(err => console.error(err))
H1HTTP response status codes
Informational responses (100 – 199)
Successful responses (200 – 299)
Redirection messages (300 – 399)
Client error responses (400 – 499)
Server error responses (500 – 599)
HTTP status codes | Description |
---|---|
200 | OK |
201 | Created |
202 | Accepted |
404 | Not Found |
H1Axios
Axios is a promise-based HTTP Client for node.js and the browser. It is isomorphic (同构的 = it can run in the browser and node.js with the same codebase).
GET: axios.get(url[, config])
POST: axios.post(url[, data[, config]])
PUT: axios.put(url[, data[, config]])
DELETE: axios.delete(url[, config])
H1SWR
H2Get Started
jsx
import useSWR from 'swr'
const fetcher = (...args) => fetch(...args).then(res => res.json());
function Profile () {
const { data, error, isLoading } = useSWR('/api/user/123', fetcher)
if (error) return <div>failed to load</div>
if (isLoading) return <div>loading...</div>
// render data
return <div>hello {data.name}!</div>
}
H3Make it reusable
jsx
function useUser (id) {
const { data, error, isLoading } = useSWR(`/api/user/${id}`, fetcher)
return {
user: data,
isLoading,
isError: error
}
}
And use it in your components:
jsx
function Avatar ({ id }) {
const { user, isLoading, isError } = useUser(id)
if (isLoading) return <Spinner />
if (isError) return <Error />
return <img src={user.avatar} />
}
H2API
const { data, error, isLoading, isValidating, mutate } = useSWR(key, fetcher, options)
H2Global Configuration
jsx
<SWRConfig value={options}>
<Component/>
</SWRConfig>
Example:
jsx
import useSWR, { SWRConfig } from 'swr'
function Dashboard () {
const { data: events } = useSWR('/api/events')
const { data: projects } = useSWR('/api/projects')
const { data: user } = useSWR('/api/user', { refreshInterval: 0 }) // override
}
function App () {
return (
<SWRConfig
value={{
refreshInterval: 3000,
fetcher: (resource, init) => fetch(resource, init).then(res => res.json())
}}
>
<Dashboard />
</SWRConfig>
)
}