Configurer une API Rest avec axum

  • rappel json response

  • axum + response type

  • negociation de contenu via entete

  • Model + serialisation

  • derive attributes

  • Deserialisation api (rename)

TODO: intro (suite du premier article)

Une API REST (également appelée API RESTful) permet d’établir une communication entre plusieurs logiciels différents en partageant des informations par l’intermédiaire du protocole HTTP.

Roy Fielding’s a longuement décrit ce principe dans sa dissertation “Architectural Styles and the Design of Network-based Software Architectures”

Pour résumer lesLes caractéristiques d’une API REST :

  • intĂ©ractions entre un serveur et un client Ă  travers la mise Ă  dispositions de ressources
  • les communications sont “stateless”, c’est Ă  dire sans persistence d’état entre les requĂŞtes. Chaque requĂŞte peut ĂŞtre jouĂ©e indĂ©pendemment.
  • mise en cache possible car il n’y a pas d’état stockĂ©
  • une interface uniforme basĂ©e sur des verbes et des ressources
  • l’architecture du système et sa complexitĂ© sous jacente ne sont pas exposĂ©s au client

Prenons un exmple avec une API qui met à dispostion des recettes de bière !

Un appel GET Ă  la ressource /beers de la version /v2:

curl -i https://api.punkapi.com/v2/beers


HTTP/2 200
date: Fri, 12 May 2023 19:36:52 GMT
content-type: application/json; charset=utf-8
access-control-allow-credentials: true
-- other headers

[
  {
    "id": 1,
    "name": "Buzz",
    "tagline": "A Real Bitter Experience.",
    "first_brewed": "09/2007",
    "description": "A light, crisp and bitter IPA brewed with English and American hops. A small batch brewed only once.",
    "image_url": "https://images.punkapi.com/v2/keg.png",
    "abv": 4.5,
    "ibu": 60,
    "target_fg": 1010,
    "target_og": 1044,
    "ebc": 20,
    "srm": 10,
    "ph": 4.4,
    "attenuation_level": 75,
    "volume": {
      "value": 20,
      "unit": "litres"
    },
    "boil_volume": {
      "value": 25,
      "unit": "litres"
    },
    "method": {
      "mash_temp": [
        {
          "temp": {
            "value": 64,
            "unit": "celsius"
          },
          "duration": 75
        }
      ],
      "fermentation": {
.... etc...

A noter que le content-type est application/json

Nous avons donc une répsonse JSON (JavaScript Object Notation).

Pour en savoir plus sur le format, consultez la spécification ECMA

Axum met Ă  disposition un type de respons Json qui prend en argument une chaine JSON

use axum::{
    body::Body,
    routing::get,
    response::Json,
    Router,
};
use serde_json::{Value, json};

// `Json` gives a content-type of `application/json` and works with any type
// that implements `serde::Serialize`
async fn json() -> Json<Value> {
    Json(json!({ "data": 42 }))
}

let app = Router::new().route("/json", get(json));

Nous construisons manuellement notre structure JSON, mais la librairie Serde va nous simplifier la vie.

La librairie serde qui contient tous les traits génériques.

Dans notre cas, nous voulons gérer du JSON, donc nous aurons besoin de serde_json