API Web§

1

Motivation§

2

Arichitecture client-serveur§

3

Hétérogénéité des clients§

Note

Même dans le cas d'une application HTML "classique", on peut bénéficier d'une API grâce à Javascript.

4

Définition§

5

Comment tester une API ?§

6

Le format JSON§

7

Présentation§

8

Sémantique§

JSON permet de représenter les données Python suivantes :

9

Exemple de données représentables en JSON§

{
  'id': 1,
  'label': "File",
  'tooltip': None,
  'items': [
    {'label': "New",   'visible': True},
    {'label': "Open",  'visible': True},
    {'label': "Close", 'visible': False},
  ],
}
10

Syntaxe§

Très similaire à Python, à quelques exceptions près :

Note

Ces variantes proviennent principalement du langage Javascript, mais aussi d'une volonté de garder le langage JSON simple.

En terme de vocabulaire,

11

Exemple précédent dans la syntaxe JSON§

{
  "id": 1,
  "label": "File",
  "tooltip": null,
  "items": [
    {"label": "New",   "visible": true},
    {"label": "Open",  "visible": true},
    {"label": "Close", "visible": false}
  ]
}
12

Utilisation en python§

En Python standard :

import json
# avec des fichiers
data = json.load(open("file.json"))
json.dump(data, open("file2.json", "w"))
# avec des chaînes de caractères
txt = json.dumps(data)
data2 = json.loads(txt)
13

Utilisation en python§

Dans Flask:

14

Verbes HTTP§

15

Introduction§

Avec HTML, on utilise exclusivement les verbes GET et POST, mais HTTP définit d'autres verbes, qui sont particulièrement utiles lors de la définition d'APIs.

16

GET§

17

PUT§

19

DELETE§

20

POST§

21

API RESTful§

Note

L'acronyme REST et ses dérivés (comme "RESTful") a été inventé par Roy Fieldings dans sa thèse.

22

Patron "collection/élément"§

23

Mise en œuvre en Flask§

Il est possible d'implémenter différents verbes dans la même vue :

@app.route("/bidules/", methods=['GET', 'POST'])
def bidules():
    if request.method == 'GET':
      # ...
    else:
      # ...
24

Mise en œuvre en Flask§

Mais il est également possible de les implémenter dans différentes vues, (et donc d'avoir plusieurs routes ayant la même URL, mais des verbes différents) :

@app.route("/bidules/", methods=['GET'])
def bidules_list():
    # ...

@app.route("/bidules/", methods=['POST'])
def bidules_new():
    # ...

Le choix entre les deux options dépend de la quantité de code commun aux traitements des différents verbes.

25

Gestion du cache§

26

Introduction§

27

En-tête Cache-control§

Voici deux valeurs typiques pour cache-control dans une réponse :

28

En-tête ETag§

29

Etag et GET§

blockdiag Client Server Reuses cached version GET /foo 200 OK Etag: "abc" GET /foo If-none-match: "abc" 304 Not Modified GET /foo If-none-match: "abc" 200 OK Etag: "cde" Resource changes
30

Etag et PUT - Concurrence optimiste§

blockdiag Client A Server Client B Resource changed GET /foo 200 OK Etag: "abc" GET /foo 200 OK Etag: "abc" PUT /foo If-match: "abc" 200 OK Etag: "def" PUT /foo If-match: "abc" 409 Conflict GET /foo 200 OK Etag: "def"
31

Mise en œuvre en Flask§

32