TP n°7 : API Web§

Votre travail§

Ajoutez au site développé au TP n°4 une API, répondant au patron “collection/éléments” vus en cours. Plus précisément, votre API comportera :

  • une collection de gènes /api/genes/,
  • un élément par gène /api/genes/<id>.

On vous suggère de procéder dans cet ordre :

GET /api/genes/<id>

fournit la représentation détaillée du gène correspondant.

Si l’identifiant fourni ne correspond à aucun gène, retourne un objet erreur avec le code 404.

GET /api/genes/

fournit les 100 premièrs gènes de la base (triés selon Ensembl_Gene_ID), sous la forme d’une liste de représentations compactes.

Si un paramètre ?offset=X est fourni, fournit les 100 premiers gènes de la base à partir du (X+1)-ième.

POST /api/genes/

accepte une représentation détaillée d’un gène à l’exception de l’attribut transcripts, et l’ajoute à la base si les conditions suivantes sont remplies ;

  • Ensemble_Gene_ID est renseigné, est une chaîne, et n’est pas un identifiant déjà présent dans la base ;
  • Chromosome_Name est renseigné, et est une chaîne ;
  • Band est une chaîne ;
  • Strand est un entier (ou non renseigné) ;
  • Gene_Start est renseigné, et est un entier ;
  • Gene_End est renseigné, est un entier, et est supérieur à Gene_Start ;
  • Associated_Gene_Name est une chaîne (ou non renseigné) ;
  • l’objet ne possède aucun autre attribut.

En cas de violation d’une de ces contraintes, retourne un objet erreur avec le code 4xx adéquat.

En cas de succès, retourne le code 201 (created) avec un objet de la forme :

{ "created": ["URL du gène créé"] }
DELETE /api/Genes/<id>

supprime le gène correspondant (s’il existe), et retourne avec un code 200 un objet de la forme :

{ "deleted": "<id>" }

Si le gène correspondant n’existe pas, la même réponse (avec un code 200) doit être retournée.

Pour aller plus loin§

  • Intégrez la gestion des etags pour les requêtes GET (en utilisant, par exemple, la date de modification du fichier sqlite).

  • Améliorez la route GET /api/Genes/ ainsi a : elle fournit désormais un objet JSON de la forme :

    {
      "items": [ "100 représentations compactes" ],
      "first": 101,
      "last": 200,
      "prev": "http://localhost:5000/api/Genes/?offset=0",
      "next": "http://localhost:5000/api/Genes/?offset=200",
    }
    
  • Améliorez la route POST /api/Genes/ ainsi : accepte désormais également une liste de d’objets correspondant chacun au modèle décrit ci-dessus.

    En cas d’échec, aucun des gènes n’est créé.

    En cas de succès, l’objet retourné est de la forme :

    {
      "created": [
        "URL du 1er gène créé",
        "URL du 2ème gène créé",
        "..."
      ]
    }
    
  • Ajoutez la route PUT /api/genes/<id> acceptant le même type de données que POST /api/Genes/, avec comme contrainte supplémentaire que Ensemble_Gene_ID doit être égal à la valeur <id> passée dans l’URL.

    Si le gène correspondant existe, il doit être modifié conformément aux données passées.

    S’il n’existe pas, il doit être créé (alternative au POST sur la collection).

  • Intégrez la gestion des etags pour le requête PUT (en cas de modification d’un gène existant).

Représentations JSON§

Représentation compacte d’un gène§

On appelle représentation compacte d’un gène un objet JSON contenant les valeurs de la table Genes, ainsi qu’un attribut href contenant l’URL du gène. Par exemple :

{
  "Ensembl_Gene_ID": "ENSG00000000003",
  "Associated_Gene_Name": "TSPAN6",
  "Chromosome_Name": "X",
  "Band": "q22.1",
  "Strand": -1,
  "Gene_End": 99894988,
  "Gene_Start": 99883667,
  "Transcript_count": 4,
  "href": "http://localhost:5000/api/Genes/ENSG00000000003"
}

Représentation détaillée d’un gène§

On appelle représentation détaillée d’un gène un objet JSON contenant les valeurs de la table Genes, ou le champs Transcript_count est remplacé par un attribut transcripts contenant les transcrits associés sous forme d’une liste d’objets, contenant chacun le nom du transcrit, sa position de départ, et sa position de fin. Par exemple :

{
  "Ensembl_Gene_ID": "ENSG00000000003",
  "Associated_Gene_Name": "TSPAN6",
  "Chromosome_Name": "X",
  "Band": "q22.1",
  "Strand": -1,
  "Gene_End": 99894988,
  "Gene_Start": 99883667,
  "transcripts": [
    {
      "Ensembl_Transcript_ID": "ENST00000373020",
      "Transcript_End": 99891803,
      "Transcript_Start": 99883667
    },
    {
      "Ensembl_Transcript_ID": "ENST00000431386",
      "Transcript_End": 99891848,
      "Transcript_Start": 99884765
    },
    {
      "Ensembl_Transcript_ID": "ENST00000496771",
      "Transcript_End": 99891686,
      "Transcript_Start": 99887538
    },
    {
      "Ensembl_Transcript_ID": "ENST00000494424",
      "Transcript_End": 99894988,
      "Transcript_Start": 99888439
    }
  ]
}

Objet erreur§

On appelle objet erreur un objet JSON possédant un unique attribut error dont la valeur est un message explicatif. Exemple :

{
  "error": "Ce gène n'existe pas"
}