Hallitse tyypitetyt API-kutsut TypeScriptissä vankkojen, ylläpidettävien ja virheettömien verkkosovellusten luomiseksi. Opi parhaat käytännöt ja edistyneet tekniikat.
Tyypitettyjen API-kutsujen hallinta TypeScriptillä: Kattava opas
Nykyaikaisessa verkkokehityksessä vuorovaikutus APIen kanssa on perustavanlaatuinen tehtävä. TypeScript, tehokkaalla tyyppijärjestelmällään, tarjoaa merkittävän edun sovellustesi luotettavuuden ja ylläpidettävyyden varmistamisessa mahdollistamalla tyypitetyt API-kutsut. Tämä opas tutkii, kuinka hyödyntää TypeScriptin ominaisuuksia vankkojen ja virheettömien API-vuorovaikutusten rakentamiseen, kattaen parhaat käytännöt, edistyneet tekniikat ja tosielämän esimerkit.
Miksi tyyppiturvallisuus on tärkeää API-kutsuissa
Kun työskentelet APIen kanssa, käsittelet pohjimmiltaan tietoa, joka tulee ulkoisesta lähteestä. Nämä tiedot eivät välttämättä aina ole odottamassasi muodossa, mikä johtaa suorituksenaikaisiin virheisiin ja odottamattomaan käyttäytymiseen. Tyyppiturvallisuus tarjoaa ratkaisevan suojakerroksen varmistamalla, että vastaanottamasi tiedot ovat ennalta määritellyn rakenteen mukaisia, ja havaitsee mahdolliset ongelmat varhaisessa kehitysvaiheessa.
- Vähentyneet suorituksenaikaiset virheet: Tyyppitarkistus käännösaikana auttaa tunnistamaan ja korjaamaan tyyppivirheet ennen kuin ne pääsevät tuotantoon.
- Parannettu koodin ylläpidettävyys: Selkeät tyyppimääritykset tekevät koodistasi helpommin ymmärrettävää ja muokattavaa, mikä vähentää virheiden riskiä uudelleenkäsittelyn aikana.
- Parannettu koodin luettavuus: Tyyppimerkinnät tarjoavat arvokasta dokumentaatiota, mikä helpottaa kehittäjien ymmärtämistä odotetuista tietorakenteista.
- Parempi kehittäjäkokemus: IDE-tuki tyyppitarkistukselle ja automaattiselle täydennykselle parantaa merkittävästi kehittäjäkokemusta ja vähentää virheiden todennäköisyyttä.
TypeScript-projektin määrittäminen
Ennen kuin sukellat API-kutsuihin, varmista, että sinulla on TypeScript-projekti määritettynä. Jos aloitat alusta, voit alustaa uuden projektin käyttämällä:
npm init -y
npm install typescript --save-dev
tsc --init
Tämä luo `tsconfig.json`-tiedoston, jossa on oletusarvoiset TypeScript-kääntäjän asetukset. Voit mukauttaa näitä asetuksia projektisi tarpeiden mukaan. Haluat ehkä esimerkiksi ottaa käyttöön tiukan tilan tiukempaa tyyppitarkistusta varten:
// tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
API-vastauksien tyyppien määrittäminen
Ensimmäinen askel tyypitettyjen API-kutsujen saavuttamiseksi on määrittää TypeScript-tyypit, jotka edustavat API:lta vastaanotettavien tietojen rakennetta. Tämä tehdään yleensä käyttämällä `interface`- tai `type`-määrityksiä.
Käyttöliittymien käyttö
Käyttöliittymät ovat tehokas tapa määrittää objektin muoto. Jos esimerkiksi haet luettelon käyttäjistä API:sta, voit määrittää käyttöliittymän seuraavasti:
interface User {
id: number;
name: string;
email: string;
address?: string; // Valinnainen ominaisuus
phone?: string; // Valinnainen ominaisuus
website?: string; // Valinnainen ominaisuus
company?: {
name: string;
catchPhrase: string;
bs: string;
};
}
`?` ominaisuuden nimen jälkeen osoittaa, että ominaisuus on valinnainen. Tämä on hyödyllistä API-vastauksien käsittelyssä, joissa tietyt kentät saattavat puuttua.
Tyyppien käyttö
Tyypit ovat samankaltaisia kuin käyttöliittymät, mutta tarjoavat enemmän joustavuutta, mukaan lukien mahdollisuuden määrittää union-tyyppejä ja intersection-tyyppejä. Voit saavuttaa saman tuloksen kuin yllä oleva käyttöliittymä käyttämällä tyyppiä:
type User = {
id: number;
name: string;
email: string;
address?: string; // Valinnainen ominaisuus
phone?: string; // Valinnainen ominaisuus
website?: string; // Valinnainen ominaisuus
company?: {
name: string;
catchPhrase: string;
bs: string;
};
};
Yksinkertaisille objektirakenteille käyttöliittymät ja tyypit ovat usein vaihdettavissa. Tyypit muuttuvat kuitenkin tehokkaammiksi, kun käsitellään monimutkaisempia skenaarioita.
API-kutsujen tekeminen Axiosilla
Axios on suosittu HTTP-asiakasohjelma API-pyyntöjen tekemiseen JavaScriptissä ja TypeScriptissä. Se tarjoaa puhtaan ja intuitiivisen API:n, mikä helpottaa erilaisten HTTP-menetelmien, pyyntöotsikoiden ja vastaustietojen käsittelyä.
Axiosin asentaminen
npm install axios
Tyypitetyn API-kutsun tekeminen
Jos haluat tehdä tyypitetyn API-kutsun Axiosilla, voit käyttää `axios.get`-menetelmää ja määrittää odotetun vastaustyypin käyttämällä geneerisiä tyyppejä:
import axios from 'axios';
async function fetchUsers(): Promise {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/users');
return response.data;
} catch (error) {
console.error('Virhe käyttäjien hakemisessa:', error);
throw error;
}
}
fetchUsers().then(users => {
users.forEach(user => {
console.log(user.name);
});
});
Tässä esimerkissä `axios.get
Eri HTTP-menetelmien käsittely
Axios tukee erilaisia HTTP-menetelmiä, mukaan lukien `GET`, `POST`, `PUT`, `DELETE` ja `PATCH`. Voit käyttää vastaavia menetelmiä tehdäksesi erityyppisiä API-pyyntöjä. Jos haluat esimerkiksi luoda uuden käyttäjän, voit käyttää `axios.post`-menetelmää:
async function createUser(user: Omit): Promise {
try {
const response = await axios.post('https://jsonplaceholder.typicode.com/users', user);
return response.data;
} catch (error) {
console.error('Virhe käyttäjän luomisessa:', error);
throw error;
}
}
const newUser = {
name: 'John Doe',
email: 'john.doe@example.com',
address: '123 Main St',
phone: '555-1234',
website: 'example.com',
company: {
name: 'Example Corp',
catchPhrase: 'Leading the way',
bs: 'Innovative solutions'
}
};
createUser(newUser).then(user => {
console.log('Luotu käyttäjä:', user);
});
Tässä esimerkissä `Omit
Fetch API:n käyttö
Fetch API on sisäänrakennettu JavaScript API HTTP-pyyntöjen tekemiseen. Vaikka se on yksinkertaisempi kuin Axios, sitä voidaan käyttää myös TypeScriptin kanssa tyypitettyjen API-kutsujen saavuttamiseksi. Voit pitää siitä enemmän, jotta vältyt riippuvuuden lisäämiseltä, jos se sopii tarpeisiisi.
Tyypitetyn API-kutsun tekeminen Fetchillä
Jos haluat tehdä tyypitetyn API-kutsun Fetchillä, voit käyttää `fetch`-funktiota ja jäsentää vastauksen JSONina määrittäen odotetun vastaustyypin:
async function fetchUsers(): Promise {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
if (!response.ok) {
throw new Error(`HTTP-virhe! status: ${response.status}`);
}
const data: User[] = await response.json();
return data;
} catch (error) {
console.error('Virhe käyttäjien hakemisessa:', error);
throw error;
}
}
fetchUsers().then(users => {
users.forEach(user => {
console.log(user.name);
});
});
Tässä esimerkissä `const data: User[] = await response.json();` kertoo TypeScriptille, että vastaustietoja tulisi käsitellä `User`-objektien taulukkoina. Tämän avulla TypeScript voi suorittaa tyyppitarkistuksen ja automaattisen täydennyksen.
Eri HTTP-menetelmien käsittely Fetchillä
Jos haluat tehdä erityyppisiä API-pyyntöjä Fetchillä, voit käyttää `fetch`-funktiota eri asetuksilla, kuten `method`- ja `body`-asetuksilla. Jos haluat esimerkiksi luoda uuden käyttäjän, voit käyttää seuraavaa koodia:
async function createUser(user: Omit): Promise {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user)
});
if (!response.ok) {
throw new Error(`HTTP-virhe! status: ${response.status}`);
}
const data: User = await response.json();
return data;
} catch (error) {
console.error('Virhe käyttäjän luomisessa:', error);
throw error;
}
}
const newUser = {
name: 'John Doe',
email: 'john.doe@example.com',
address: '123 Main St',
phone: '555-1234',
website: 'example.com',
company: {
name: 'Example Corp',
catchPhrase: 'Leading the way',
bs: 'Innovative solutions'
}
};
createUser(newUser).then(user => {
console.log('Luotu käyttäjä:', user);
});
API-virheiden käsittely
Virheiden käsittely on kriittinen osa API-kutsuja. API:t voivat epäonnistua monista syistä, mukaan lukien verkkoyhteysongelmat, palvelinvirheet ja virheelliset pyynnöt. On tärkeää käsitellä nämä virheet siististi, jotta sovelluksesi ei kaatuisi tai näyttäisi odottamatonta käyttäytymistä.
Try-Catch-lohkojen käyttö
Yleisin tapa käsitellä virheitä asynkronisessa koodissa on käyttää try-catch-lohkoja. Tämän avulla voit napata kaikki API-kutsun aikana heitetyt poikkeukset ja käsitellä ne asianmukaisesti.
async function fetchUsers(): Promise {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/users');
return response.data;
} catch (error) {
console.error('Virhe käyttäjien hakemisessa:', error);
// Käsittele virhe, esim. näytä virheilmoitus käyttäjälle
throw error; // Heitä virhe uudelleen, jotta kutsuva koodi voi myös käsitellä sen
}
}
Erityisten virhekoodien käsittely
API:t palauttavat usein erityisiä virhekoodeja osoittamaan tapahtuneen virheen tyypin. Voit käyttää näitä virhekoodeja tarjotaksesi tarkempaa virheiden käsittelyä. Haluat ehkä esimerkiksi näyttää erilaisen virheilmoituksen 404 Not Found -virheelle kuin 500 Internal Server Error -virheelle.
async function fetchUser(id: number): Promise {
try {
const response = await axios.get(`https://jsonplaceholder.typicode.com/users/${id}`);
return response.data;
} catch (error: any) {
if (error.response?.status === 404) {
console.log(`Käyttäjää ID:llä ${id} ei löytynyt.`);
return null; // Tai heitä mukautettu virhe
} else {
console.error('Virhe käyttäjän hakemisessa:', error);
throw error;
}
}
}
fetchUser(123).then(user => {
if (user) {
console.log('Käyttäjä:', user);
} else {
console.log('Käyttäjää ei löytynyt.');
}
});
Mukautettujen virhetyyppien luominen
Monimutkaisempia virheidenkäsittelyskenaarioita varten voit luoda mukautettuja virhetyyppejä, jotka edustavat erityyppisiä API-virheitä. Tämän avulla voit tarjota jäsennellympiä virhetietoja ja käsitellä virheitä tehokkaammin.
class ApiError extends Error {
constructor(public statusCode: number, message: string) {
super(message);
this.name = 'ApiError';
}
}
async function fetchUser(id: number): Promise {
try {
const response = await axios.get(`https://jsonplaceholder.typicode.com/users/${id}`);
return response.data;
} catch (error: any) {
if (error.response?.status === 404) {
throw new ApiError(404, `Käyttäjää ID:llä ${id} ei löytynyt.`);
} else {
console.error('Virhe käyttäjän hakemisessa:', error);
throw new ApiError(500, 'Sisäinen palvelinvirhe'); //Tai mikä tahansa muu sopiva tilakoodi
}
}
}
fetchUser(123).catch(error => {
if (error instanceof ApiError) {
console.error(`API-virhe: ${error.statusCode} - ${error.message}`);
} else {
console.error('Tapahtui odottamaton virhe:', error);
}
});
Datan validointi
Vaikka TypeScriptillä on tyyppijärjestelmä, on erittäin tärkeää validoida API:sta vastaanottamasi data suorituksen aikana. API:t voivat muuttaa vastausrakennettaan ilman erillistä ilmoitusta, ja TypeScript-tyyppisi eivät välttämättä aina ole täydellisesti synkronoitu API:n todellisen vastauksen kanssa.
Zodin käyttö suorituksenaikaiseen validointiin
Zod on suosittu TypeScript-kirjasto suorituksenaikaiseen datan validointiin. Sen avulla voit määrittää skeemoja, jotka kuvaavat odotettua datarakenteesi ja validoida sitten datan kyseisiä skeemoja vasten suorituksen aikana.
Zodin asentaminen
npm install zod
API-vastausten validointi Zodin avulla
Jos haluat validoida API-vastauksia Zodin avulla, voit määrittää Zod-skeeman, joka vastaa TypeScript-tyyppiäsi, ja käyttää sitten `parse`-menetelmää datan validoimiseen.
import { z } from 'zod';
const userSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string().email(),
address: z.string().optional(),
phone: z.string().optional(),
website: z.string().optional(),
company: z.object({
name: z.string(),
catchPhrase: z.string(),
bs: z.string(),
}).optional(),
});
type User = z.infer;
async function fetchUsers(): Promise {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/users');
const data = z.array(userSchema).parse(response.data);
return data;
} catch (error) {
console.error('Virhe käyttäjien hakemisessa:', error);
throw error;
}
}
Tässä esimerkissä `z.array(userSchema).parse(response.data)` validioi, että vastaustiedot ovat objektien taulukko, jotka vastaavat `userSchema`-skeemaa. Jos data ei vastaa skeemaa, Zod heittää virheen, jonka voit sitten käsitellä asianmukaisesti.
Edistyneet tekniikat
Geneeristen tyyppien käyttö uudelleenkäytettäviä API-funktioita varten
Geneeristen tyyppien avulla voit kirjoittaa uudelleenkäytettäviä API-funktioita, jotka voivat käsitellä erityyppisiä tietoja. Voit esimerkiksi luoda geneerisen `fetchData`-funktion, joka voi hakea tietoja mistä tahansa API-päätepisteestä ja palauttaa ne oikealla tyypillä.
async function fetchData(url: string): Promise {
try {
const response = await axios.get(url);
return response.data;
} catch (error) {
console.error(`Virhe tietojen hakemisessa osoitteesta ${url}:`, error);
throw error;
}
}
// Käyttö
fetchData('https://jsonplaceholder.typicode.com/users').then(users => {
console.log('Käyttäjät:', users);
});
fetchData<{ title: string; body: string }>('https://jsonplaceholder.typicode.com/todos/1').then(todo => {
console.log('Todo', todo)
});
Välittäjien käyttö globaaliin virheidenhallintaan
Axios tarjoaa välittäjiä, joiden avulla voit siepata pyyntöjä ja vastauksia ennen kuin koodisi käsittelee niitä. Voit käyttää välittäjiä globaalin virheidenhallinnan toteuttamiseen, kuten virheiden kirjaamiseen tai virheilmoitusten näyttämiseen käyttäjälle.
axios.interceptors.response.use(
(response) => response,
(error) => {
console.error('Globaali virheenkäsittelijä:', error);
// Näytä virheilmoitus käyttäjälle
return Promise.reject(error);
}
);
Ympäristömuuttujien käyttö API-URL-osoitteille
Välttääksesi API-URL-osoitteiden kovakoodaamista koodissasi, voit käyttää ympäristömuuttujia URL-osoitteiden tallentamiseen. Tämä helpottaa sovelluksesi määrittämistä eri ympäristöihin, kuten kehitys-, testaus- ja tuotantoympäristöihin.
Esimerkki `.env`-tiedoston ja `dotenv`-paketin käytöstä.
// .env
API_URL=https://api.example.com
// Asenna dotenv
npm install dotenv
// Tuo ja määritä dotenv
import * as dotenv from 'dotenv'
dotenv.config()
const apiUrl = process.env.API_URL || 'http://localhost:3000'; // anna oletusarvo
async function fetchData(endpoint: string): Promise {
try {
const response = await axios.get(`${apiUrl}/${endpoint}`);
return response.data;
} catch (error) {
console.error(`Virhe tietojen hakemisessa osoitteesta ${apiUrl}/${endpoint}:`, error);
throw error;
}
}
Johtopäätös
Tyypitetyt API-kutsut ovat välttämättömiä vankkojen, ylläpidettävien ja virheettömien verkkosovellusten rakentamiseen. TypeScript tarjoaa tehokkaita ominaisuuksia, joiden avulla voit määrittää tyyppejä API-vastauksille, validoida dataa suorituksen aikana ja käsitellä virheitä siististi. Noudattamalla tässä oppaassa esitettyjä parhaita käytäntöjä ja tekniikoita voit parantaa merkittävästi API-vuorovaikutustesi laatua ja luotettavuutta.
Käyttämällä TypeScriptiä ja kirjastoja, kuten Axios ja Zod, voit varmistaa, että API-kutsusi ovat tyyppiturvallisia, datasi on validoitu ja virheesi käsitellään siististi. Tämä johtaa vankempiin ja ylläpidettävämpiin sovelluksiin.
Muista aina validoida datasi suorituksen aikana, jopa TypeScriptin tyyppijärjestelmän kanssa. API:t voivat muuttua, ja tyyppisi eivät välttämättä aina ole täydellisesti synkronoitu API:n todellisen vastauksen kanssa. Validoimalla datasi suorituksen aikana voit havaita mahdolliset ongelmat ennen kuin ne aiheuttavat ongelmia sovelluksessasi.
Hyvää koodausta!