Typage des API REST en Typescript

Salut à tous ! Aujourd'hui, plongeons dans les profondeurs des API REST avec Typescript.

Nous allons voir comment typer les requêtes et les réponses d'API pour assurer une navigation en toute sécurité à travers ces vastes océans de données. 🐠🌊

Préparer le Terrain

Avant de plonger, assure-toi d'avoir une configuration de projet avec Typescript et un outil pour effectuer des requêtes HTTP, comme axios.

Installation de axios et Types d'Interface

Installe axios et les types d'interface pour Typescript :

npm install axios
npm install @types/axios

Typage des Requêtes API

Imaginons que notre API sous-marine nous permet de récupérer des informations sur des créatures marines. Typons nos requêtes et réponses pour rendre notre exploration plus sûre et efficace.

Interface pour les Données de Créature Marine

Définissons une interface pour les créatures marines :

interface MarineCreature {
  id: number
  name: string
  habitat: string
  size: number
}

Fonction pour Récupérer les Créatures

Utilisons axios pour récupérer les données de notre API et typons la réponse :

import axios from 'axios'

async function getMarineCreatures(): Promise<MarineCreature[]> {
  try {
    const response = await axios.get<MarineCreature[]>(
      '<https://api.oceanlife.com/creatures>',
    )
    return response.data
  } catch (error) {
    throw new Error(
      `Erreur lors de la récupération des créatures marines : ${error.message}`,
    )
  }
}

getMarineCreatures().then((creatures) => {
  creatures.forEach((creature) => {
    console.log(`Créature : ${creature.name}, Habitat : ${creature.habitat}`)
  })
})

Gestion des Réponses d'API

Pour gérer les réponses de manière efficace, nous devons également typer les réponses d'API. Cela nous permet de manipuler les données en toute confiance.

Interface pour les Réponses Paginated

Si notre API retourne des données paginées, nous devons typer cette structure :

interface PaginatedResponse<T> {
  data: T[]
  currentPage: number
  totalPages: number
}

async function getPaginatedMarineCreatures(
  page: number,
): Promise<PaginatedResponse<MarineCreature>> {
  try {
    const response = await axios.get<PaginatedResponse<MarineCreature>>(
      `https://api.oceanlife.com/creatures?page=${page}`,
    )
    return response.data
  } catch (error) {
    throw new Error(
      `Erreur lors de la récupération des créatures marines paginées : ${error.message}`,
    )
  }
}

getPaginatedMarineCreatures(1).then((response) => {
  console.log(`Page ${response.currentPage} sur ${response.totalPages}`)
  response.data.forEach((creature) => {
    console.log(`Créature : ${creature.name}, Habitat : ${creature.habitat}`)
  })
})

Typage des Paramètres d'API

Typage des paramètres d'API garantit que nous envoyons toujours les bonnes données au serveur.

Interface pour les Paramètres de Filtrage

Si notre API permet de filtrer les créatures par habitat et taille, nous pouvons typer ces paramètres :

interface FilterParams {
  habitat?: string
  minSize?: number
  maxSize?: number
}

async function filterMarineCreatures(
  params: FilterParams,
): Promise<MarineCreature[]> {
  try {
    const response = await axios.get<MarineCreature[]>(
      '<https://api.oceanlife.com/creatures>',
      { params },
    )
    return response.data
  } catch (error) {
    throw new Error(
      `Erreur lors du filtrage des créatures marines : ${error.message}`,
    )
  }
}

filterMarineCreatures({ habitat: 'Coral Reef', minSize: 10 }).then(
  (creatures) => {
    creatures.forEach((creature) => {
      console.log(`Créature : ${creature.name}, Habitat : ${creature.habitat}`)
    })
  },
)

Manipulation des Erreurs d'API

Les erreurs peuvent survenir lorsque nous explorons les profondeurs de l'océan. Gérons ces erreurs pour éviter les naufrages.

Typage des Erreurs d'API

Nous pouvons typer les erreurs pour mieux les manipuler :

interface ApiError {
  message: string
  code: number
}

async function getMarineCreatureById(id: number): Promise<MarineCreature> {
  try {
    const response = await axios.get<MarineCreature>(
      `https://api.oceanlife.com/creatures/${id}`,
    )
    return response.data
  } catch (error) {
    const apiError: ApiError = {
      message: error.message,
      code: error.response.status,
    }
    throw apiError
  }
}

getMarineCreatureById(1).catch((error) => {
  console.error(`Erreur ${error.code} : ${error.message}`)
})

Générer des Types à partir d'un Objet JSON

Imaginons que nous avons un objet JSON provenant de notre API et que nous voulons générer des types à partir de cet objet.

Utiliser json2ts

Un outil populaire pour générer des types à partir de JSON est json2ts.

Tu peux l'installer via npm et l'utiliser pour convertir un fichier JSON en interfaces Typescript.

npm install -g json2ts

Ensuite, exécute la commande suivante pour convertir un fichier JSON en Typescript :

json2ts oceanlife.json

Exemple de Conversion

Imaginons que nous avons le JSON suivant :

{
  "id": 1,
  "name": "Great White Shark",
  "habitat": "Ocean",
  "size": 5000
}

Utilise json2ts pour générer l'interface :

export interface MarineCreature {
  id: number
  name: string
  habitat: string
  size: number
}

Code Generation avec openapi-generator

Pour automatiser la génération des types et des clients API, tu peux utiliser des outils comme openapi-generator, qui génèrent du code Typescript à partir d'une spécification OpenAPI.

Installation et Utilisation

Installe openapi-generator via npm :

npm install @openapitools/openapi-generator-cli -g

Ensuite, utilise la commande suivante pour générer du code Typescript à partir d'un fichier de spécification OpenAPI :

openapi-generator-cli generate -i openapi.yaml -g typescript-axios -o src/api

Cela génère un client API entièrement typé pour interagir avec ton API REST.

Intégration avec GraphQL

GraphQL est une alternative puissante aux API REST, permettant de demander exactement les données dont tu as besoin. Typage et génération de code sont également possibles avec GraphQL.

Utiliser graphql-codegen

graphql-codegen est un outil qui génère du code Typescript à partir de schémas et de requêtes GraphQL.

Installation

Installe les packages nécessaires :

npm install @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typescript-graphql-request

Configuration et Génération

Crée un fichier de configuration codegen.yml :

schema: <https://api.oceanlife.com/graphql>
documents: 'src/**/*.graphql'
generates:
  src/generated/graphql.ts:
    plugins:
      - typescript
      - typescript-operations
      - typescript-graphql-request

Exécute la génération avec la commande suivante :

npx graphql-codegen

Cela génère des types Typescript et des hooks pour interagir avec ton API GraphQL.

Utilisation des Types Générés

Utilise les types générés dans ton code :

import { GraphQLClient } from 'graphql-request'
import { getSdk } from './generated/graphql'

const client = new GraphQLClient('<https://api.oceanlife.com/graphql>')
const sdk = getSdk(client)

sdk.getMarineCreatures().then((data) => {
  data.creatures.forEach((creature) => {
    console.log(`Créature : ${creature.name}, Habitat : ${creature.habitat}`)
  })
})

Conclusion

Naviguer dans les API REST et GraphQL avec Typescript permet de rendre notre exploration des données sous-marines plus sûre et précise. En typant les requêtes, les réponses et les erreurs, et en utilisant des outils de génération de code, nous pouvons éviter les pièges cachés et profiter pleinement de notre aventure !

Tags

  • tutorial
  • typescript

Cet article à été posté le