Guide d’utilisation de AgorAPI

Cette page décrit les différentes fonctionnalités offertes par AgorAPI, à partir d’exemples simples.

  1. Généralités : ressources, authentification
  2. Utilisation standard : créer une consultation, voter, obtenir les résultats
  3. Votes nuancés (par classement) : effectuer un vote nuancé, comprendre les résultats
  4. Gestion utilisateurs : créer des utilisateurs, les faire voter

Généralités Retour

Ressources

AgorAPI est une API REST, ce qui signifie que les points d’entrée (adresses URL) correspondent à des ressources, et que les méthodes HTTP permettent d’interagir avec elles:

Parmi les ressources, on retrouve : les consultations (polls), les choix (choices) (les propositions d’une consultation), les votes, les résultats (results), et les diagrammes (charts). La plupart d’entre elles sont identifiées par un ID unique (qui consiste en une suite de caractères alphanumériques), généré automatiquement pour vous. Cet ID est retourné à chaque fois qu’une nouvelle ressource est créée, et peut être utilisé par la suite pour désigner cette ressource.

Échanges de données

Lors de l’envoi d’une requête GET, des paramètres peuvent être ajoutés en fin d’URL (query string), en particulier pour rechercher des ressources (par exemple, poll_id=P123456789). Pour les requêtes POST, PUT et PATCH, des données sont attendues dans le corps de la requête, et doivent être encodées au format JSON.

Chaque requête à l’API donne lieu à une réponse du serveur. Si la requête a échoué, le code de retour de la réponse indique la raison, parmi :

En cas de réussite, le code de retour de la réponse est en général 200, et le corps de la réponse contient les données attendues au format JSON (ressources récupérées, ou données effectivement ajoutées ou modifiées). Par exemple, en réponse à une demande de liste des choix de la consultation P123456789, l’API pourrait retourner le contenu suivant :

[
    {
        "id": "C111111111",
        "poll_id": "P123456789",
        "num": 1,
        "label": "first choice",
        "description": null,
        "image_url": null
    },
    {
        "id": "C222222222",
        "poll_id": "P123456789",
        "num": 2,
        "label": "second choice",
        "description": null,
        "image_url": null
    },
    {
        "id": "C333333333",
        "poll_id": "P123456789",
        "num": 3,
        "label": "third choice",
        "description": null,
        "image_url": null
    }
    ]

Il y a 2 exceptions notables au code de retour :

Authentification

Pour assurer la confidentialité et la sécurité de vos données, toutes les requêtes à l’API doivent être identifiées, au moyen d’un jeton (token), envoyé comme paramètre de requête sous le nom api_token. Ce jeton (obtenu dans votre compte) authentifie la requête entrante comme provenant bien de vous, et lui donnera donc un accès complet (lecture et écriture) à vos données. En conséquence, vous devez absolument faire en sorte de garder vos jetons secrets ! (Néanmoins, en cas de fuite, si un jeton est compromis, vous pouvez à tout moment le remplacer par un nouveau depuis votre interface de gestion de jetons.)

Du côté de l’API, toutes les requêtes sont chiffrées avec SSL/TLS, nos serveurs ne répondant qu’aux requêtes HTTPS.

Un jeton manquant ou erroné donnera lieu aux codes de retour suivants :

De plus, une erreur 403 est renvoyée lorsque vous êtes correctement identifié mais que vous ne disposez plus de crédits.

Un jeton est lié à un « scope », avec lequel il peut interagir. Un autre jeton aura un scope différent, de manière à pouvoir utiliser des jetons différents pour des applications différentes (une consultation créée avec un jeton n’existera pas pour les autres jetons). Si nécessaire, ou en cas de doute sur le fait qu’un jeton aurait fuité, vous pouvez le remplacer par un autre dans votre compte. Ce nouveau jeton aura les mêmes droits que le précédent, celui-ci cessant de fonctionner dès son remplacement.

Exemples

Les parties suivantes de ce guide contiennent de nombreux exemples de requêtes. Vous pouvez facilement les reproduire de votre côté dans un terminal, à l’aide des exemples cURL fournis (à installer avec votre gestionnaire de paquets, ou depuis le site officiel). Ces exemples se présentent comme ceci :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/info?api_token=$API_TOKEN"

L’option -i active l’affichage des en-têtes de la réponse (utile pour vérifier le code de retour et visualiser les éventuels liens vers les pages de résultats suivantes), -H initialise certains en-têtes et -X spécifie la méthode de la requête. Ces commandes présupposent que la variable shell API_TOKEN est définie, et contient votre jeton d’identification. Pour ce faire, exécutez simplement

API_TOKEN=<remplacer par votre jeton>

La commande cURL ci-dessus est un bon moyen de débuter avec l’API, et de vérifier que votre jeton fonctionne correctement. Si c’est bien le cas, vous devriez recevoir les informations associées au jeton, sinon le code de retour et le corps de la réponse vous diront d’où vient l’erreur.

Utilisation standard Retour

Créer une consultation

Pour créer une consultation, il suffit d’envoyer une ressource poll avec la méthode POST, en encodant cette consultation en JSON et en l’envoyant dans le corps de la requête (option -d de cURL). Pour plus de simplicité, le point d’entrée /polls/with-choices permet de créer une consultation contenant déjà un certain nombre de choix :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/polls/with-choices?api_token=$API_TOKEN" \
     -d '{"title": "My poll title", "choices": [{"label": "first choice"}, {"label": "second choice"}]}'

Cette commande devrait renvoyer (avec un code de retour 200) un contenu JSON proche de celui-ci :

{
    "id": "P123456789",
    "creation_date": "2017-06-01T12:00:00.000000+02:00",
    "user_id": "U000000001",
    "title": "My poll title",
    "description": null,
    "poll_status": "OPEN",
    "options": {
        "anonymous": false
    },
    "choices": [
    {
        "id": "C111111111",
        "poll_id": "P123456789",
        "num": 1,
        "label": "first choice",
        "description": null,
        "image_url": null
    },
    {
        "id": "C222222222",
        "poll_id": "P123456789",
        "num": 2,
        "label": "second choice",
        "description": null,
        "image_url": null
    }
    ]
}

Remarquez que les identifiants générés (de la consultation et des choix) sont bien renvoyés, de façon à pouvoir les réutiliser par la suite.

Il est possible de rajouter des choix supplémentaires à tout moment, en utilisant le point d’entrée /choices (un seul choix) ou /choices/for-poll/P123456789 (choix multiples) :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/choices?api_token=$API_TOKEN" \
     -d '{"poll_id": "P123456789", "label": "third choice"}'
{
    "id": "C333333333",
    "poll_id": "P123456789",
    "num": 3,
    "label": "third choice",
    "description": null,
    "image_url": null
}

Encore une fois, on remarque le nouvel identifiant, et la numérotation automatique du choix (num vaut 3, puisqu’il s’agit bien du troisième choix ajoutés à cette consultation).

Voter

Avant de voter, il peut être utile de lister les propositions envisageables. Pour cela, effectuez une requête GET sur le point d’entrée /choices, avec le paramètre poll_id:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/choices?api_token=$API_TOKEN&poll_id=P123456789"
[
    {
        "id": "C111111111",
        "poll_id": "P123456789",
        "num": 1,
        "label": "first choice",
        "description": null,
        "image_url": null
    },
    {
        "id": "C222222222",
        "poll_id": "P123456789",
        "num": 2,
        "label": "second choice",
        "description": null,
        "image_url": null
    },
    {
        "id": "C333333333",
        "poll_id": "P123456789",
        "num": 3,
        "label": "third choice",
        "description": null,
        "image_url": null
    }
    ]

Il faut se rappeler que cette requête peut renvoyer un code de retour 206, dans le cas où il y aurait beaucoup de choix. Il faut donc toujours vérifier le code de retour de la réponse, pour s’assurer que l’on a bien reçu tous les résultats.

Voter pour son choix préféré revient à envoyer le poll_id et choice_id au point d’entrée /votes :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/votes?api_token=$API_TOKEN" \
     -d '{"poll_id": "P123456789", "choice_id": "C111111111"}'
{
    "vote_date": "2017-06-01T12:10:00.000000+02:00",
    "user": {
        "id": "U000000002",
        "name": null,
        "email": null
    },
    "poll_id": "P123456789",
    "choice_id": "C111111111",
    "rank": 1
}

Il est possible de voter pour plusieurs choix, en envoyant la liste des choix souhaités au point d’entrée /votes/for-poll/P123456789 :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/votes/for-poll/P123456789?api_token=$API_TOKEN" \
     -d '[{"choice_id": "C111111111"}, {"choice_id": "C333333333"}]'
[
    {
        "vote_date": "2017-06-01T12:20:00.000000+02:00",
        "user": {
            "id": "U000000003",
            "name": null,
            "email": null
        },
        "poll_id": "P123456789",
        "choice_id": "C111111111",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:20:00.000000+02:00",
        "user": {
            "id": "U000000003",
            "name": null,
            "email": null
        },
        "poll_id": "P123456789",
        "choice_id": "C333333333",
        "rank": 1
    }
    ]

Obtenir les résultats

Avant de demander les résultats, on peut vouloir lister les votes déjà effectués :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/votes?api_token=$API_TOKEN&poll_id=P123456789"
[
    {
        "vote_date": "2017-06-01T12:10:00+02:00",
        "user": {
            "id": "U000000002",
            "name": null,
            "email": null
        },
        "poll_id": "P123456789",
        "choice_id": "C111111111",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:20:00+02:00",
        "user": {
            "id": "U000000003",
            "name": null,
            "email": null
        },
        "poll_id": "P123456789",
        "choice_id": "C111111111",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:20:00+02:00",
        "user": {
            "id": "U000000003",
            "name": null,
            "email": null
        },
        "poll_id": "P123456789",
        "choice_id": "C333333333",
        "rank": 1
    }
    ]

Encore une fois, attention à l’éventuel code de retour 206, qui indique une réponse partielle.

Les résultats peuvent être obtenus sur les points d’entrée /polls/P123456789/results/{result-type}. Le résultat le plus classique est le décompte majoritaire (majority) des votes :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/polls/P123456789/results/majority?api_token=$API_TOKEN"
[
    {
        "choice": {
            "id": "C111111111",
            "poll_id": "P123456789",
            "num": 1,
            "label": "first choice",
            "description": null,
            "image_url": null
        },
        "rank": 1,
        "score": 2
    },
    {
        "choice": {
            "id": "C333333333",
            "poll_id": "P123456789",
            "num": 3,
            "label": "third choice",
            "description": null,
            "image_url": null
        },
        "rank": 2,
        "score": 1
    },
    {
        "choice": {
            "id": "C222222222",
            "poll_id": "P123456789",
            "num": 2,
            "label": "second choice",
            "description": null,
            "image_url": null
        },
        "rank": 3,
        "score": 0
    }
    ]

Comme on peut le voir, un résultat est une liste (potentiellement paginée) d’entrées, elles-mêmes consistant en un choix associé à un rang et à un score. Ces entrées sont triées par rang croissant et score décroissant (les meilleurs choix en premier). Dans le cas du vote majoritaire, les scores indiquent le nombre de fois que chaque choix a été plébiscité, ici deux fois pour le choix 1 et une fois pour le choix 3 (voir plus haut la liste des votes).

AgorAPI permet une représentation plus visuelle des résultats, en offrant la possibilité de générer des diagrammes (charts) de résultats. On peut obtenir l’URL d’un diagramme avec un appel à /polls/P123456789/results/majority/charts/{chart-type}, où {chart-type} peut être :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/polls/P123456789/results/majority/charts/vbar?api_token=$API_TOKEN"
{
    "id": "gr34tCh4rt",
    "poll_id": "P123456789",
    "chart_type": "vbar",
    "result_type": "majority",
    "title": "My poll title",
    "url": "http://chart.open-agora.com/gr34tCh4rt"
}

Maintenant, en ouvrant l’URL reçue en réponse, vous pouvez télécharger les diagrammes !

Exemple de diagramme vbar

Représentation des résultats sous forme de diagramme à barres verticales

Exemple de diagramme pie

Représentation des résultats sous forme de diagramme circulaire

Notez que pour mettre à jour un diagramme après un nouveau vote, il faut refaire une requête GET à /polls/P123456789/results/majority/charts/{chart-type} (ou, de façon équivalente, une requête PUT à /charts/{chart-id}/update, où chart_id est l’identifiant reçu à la création du diagramme, dans notre exemple gr34tCh4rt). La mise à jour du diagramme ne modifie pas son URL, mais actualise la représentation des résultats.

Enfin, une fois la consultation terminée, vous pouvez la clore (close) pour empêcher l’enregistrement de tout nouveau vote. Clore une consultation consiste à mettre à jour son statut avec la valeur CLOSED :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X PATCH "https://api.open-agora.com/polls/P123456789?api_token=$API_TOKEN" \
     -d '{"poll_status": "CLOSED"}'
{
    "id": "P123456789",
    "creation_date": "2017-06-01T12:00:00.000000+02:00",
    "user_id": "U000000001",
    "title": "My poll title",
    "description": null,
    "poll_status": "CLOSED",
    "options": {
        "anonymous": false
    }
}

Une consultation close peut être rouverte à tout moment, en remettant son statut à OPEN, et ainsi de suite.

Vous êtes maintenant prêts à utiliser AgorAPI pour vos consultations ! La suite de ce guide les fonctionnalités plus avancées d’AgorAPI.

Votes nuancés Retour

Classer les choix

Une fonctionnalité originale d’AgorAPI est la possibilité d’émettre des votes nuancés, en classant les choix. En pratique, cela signifie que chaque votant peut indiquer un niveau de préférence pour chaque choix. Ceci peut être réalisé en associant à chaque vote un rang : les rangs débutent à 1 (valeur par défaut si omis) pour indiquer les propositions préférées, et augmentent au fur et à mesure que le niveau de préférence baisse :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/votes/for-poll/P123456789?api_token=$API_TOKEN" \
     -d '[{"choice_id": "C222222222", "rank": 1}, {"choice_id": "C333333333", "rank": 2}]'
[
    {
        "vote_date": "2017-06-01T12:30:00+02:00",
        "user": {
            "id": "U000000004",
            "name": null,
            "email": null
        },
        "poll_id": "P123456789",
        "choice_id": "C222222222",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:30:00+02:00",
        "user": {
            "id": "U000000004",
            "name": null,
            "email": null
        },
        "poll_id": "P123456789",
        "choice_id": "C333333333",
        "rank": 2
    }
    ]

Ce vote signifie que l’utilisateur préfère le choix 2, puis vient le choix 3, tous les choix restants étant classés derniers.

Résultats

L’intérêt principal d’un tel vote est d’être plus riche et plus expressif qu’un vote par approbation classique, et qu’il peut être utilisé pour obtenir un résultat plus consensuel, tenant compte des préférences exprimées par chaque votant. En particulier, les résultats peuvent être calculés selon les méthodes de Condorcet (voir cet article pour plus de précisions sur l’algorithme utilisé) ou du vote alternatif.

Le résultat du vote alternatif peut être demandé via la route /polls/P123456789/results/runoff. Étant donné qu’il s’agit d’une généralisation du résultat majoritaire à n tours, les scores indiquent le nombre de voix reçues au dernier tour, et l’affichage graphique idéal est également obtenu avec des diagrammes vbar ou pie.

Dans notre exemple, si par contre nous demandons le résultat Condorcet, les résultats restent triés, mais le score exprime le degré de satisfaction global d’un choix (sur une échelle de 0 à 100) :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/polls/P123456789/results/condorcet?api_token=$API_TOKEN"
[
    {
        "choice": {
            "id": "C111111111",
            "poll_id": "P123456789",
            "num": 1,
            "label": "first choice",
            "description": null,
            "image_url": null
        },
        "rank": 1,
        "score": 67
    },
    {
        "choice": {
            "id": "C333333333",
            "poll_id": "P123456789",
            "num": 3,
            "label": "third choice",
            "description": null,
            "image_url": null
        },
        "rank": 1,
        "score": 67
    },
    {
        "choice": {
            "id": "C222222222",
            "poll_id": "P123456789",
            "num": 2,
            "label": "second choice",
            "description": null,
            "image_url": null
        },
        "rank": 3,
        "score": 0
    }
    ]

Le résultat Condorcet est représenté idéalement avec un diagramme à barres horizontales (où l’axe des abscisses exprime un pourcentage) :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/polls/P123456789/results/condorcet/charts/hbar?api_token=$API_TOKEN"
{
    "id": "n1c4rCh4rt",
    "poll_id": "P123456789",
    "chart_type": "hbar",
    "result_type": "condorcet",
    "title": "My poll title",
    "url": "http://chart.open-agora.com/n1c4rCh4rt"
}

Exemple de diagramme hbar

Représentation d’un résultat Condorcet par un diagramme à barres horizontales

Gestion des utilisateurs Retour

Utilisateurs

Pour conclure, lorsque l’application qui utilise AgorAPI dispose d’une notion d’utilisateur, l’API permet également :

Les utilisateurs côté AgorAPI sont créés par l’intermédiaire de la route /users :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/users?api_token=$API_TOKEN" \
     -d '{}'
{
    "id": "U100000000",
    "email": null,
    "name": null
}

Dans cet exemple, nous n’avons ajouté aucune donnée relative à l’utilisateur, mais si nécessaire, une adresse email et/ou un nom (chaînes arbitraires permettant d’identifier l’utilisateur côté application) peuvent être ajoutés.

Voter

Les identifiants utilisateurs peuvent être envoyés à l’API lors de :

Cette dernière possibilité est accomplie en envoyant un paramètre user avec attribut id dans la ressource de vote envoyée à /votes, ou bien en ajoutant cet identifiant à l’adresse du point d’entrée /votes/for-poll/P123456789/for-user/{user-id}. La seconde adresse est plus souple : plusieurs votes (pour plusieurs choix) peuvent être envoyés d’un coup, et ces votes peuvent remplacer (méthode PUT) ou compléter (méthode POST) le vote existant pour cet utilisateur. Dans les deux cas, il est possible d’indiquer un nom (name) ou un email (email) dans l’objet user, pour indiquer ou modifier les données de l’utilisateur tout en votant.

Remarquez que même dans le cas d’une requête POST, puisqu’un utilisateur ne peut avoir qu’un seul classement pour un choix, tout vote existant de l’utilisateur sur un des choix donnés sera supprimé et remplacé par le nouveau. Ici, nous inversons l’ordre du vote de l’utilisateur U000000004 envoyé plus tôt, dans la partie 3 :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/votes/for-poll/P123456789/for-user/U000000004?api_token=$API_TOKEN" \
     -d '[{"choice_id": "C333333333", "rank": 1}, {"choice_id": "C222222222", "rank": 2}]'
[
    {
        "vote_date": "2017-06-01T12:40:00+02:00",
        "user": {
            "id": "U000000004",
            "name": null,
            "email": null
        },
        "poll_id": "P123456789",
        "choice_id": "C333333333",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:40:00+02:00",
        "user": {
            "id": "U000000004",
            "name": null,
            "email": null
        },
        "poll_id": "P123456789",
        "choice_id": "C222222222",
        "rank": 2
    }
    ]

On peut noter qu’en l’absence d’identifiant utilisateur dans la requête de vote (corps ou URL), c’est un nouvel utilisateur qui est créé pour l’occasion. Ce nouvel utilisateur est renvoyé dans la réponse, comme c’était le cas dans les exemples de votes de la partie 2.

Consultations anonymes

Enfin, l’API permet de créer des consultations anonymes. Cela peut être indiqué dès la création de la consultation en initialisant l’option anonymous à la valeur true, ou plus tard, en mettant la consultation à jour :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X PATCH "https://api.open-agora.com/polls/P123456789?api_token=$API_TOKEN" \
     -d '{"options": {"anonymous": true}}'
{
    "id": "P123456789",
    "creation_date": "2017-06-01T12:00:00.000000+02:00",
    "user_id": "U000000001",
    "title": "My poll title",
    "description": null,
    "poll_status": "OPEN",
    "options": {
        "anonymous": true
    }
}

Il faut bien noter que pour préserver la confidentialité des votes existants, une consultation anonyme ne peut plus redevenir non-anonyme !

Une fois la consultation devenue anonyme, la seule chose qui change est l’impossibilité de pouvoir associer les votes aux utilisateurs. Les votes récupérés depuis l’API seront ainsi renvoyés avec un user vide :

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/votes?api_token=$API_TOKEN&poll_id=P123456789"
[
    {
        "vote_date": "2017-06-01T12:10:00+02:00",
        "user": null,
        "poll_id": "P123456789",
        "choice_id": "C111111111",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:20:00+02:00",
        "user": null,
        "poll_id": "P123456789",
        "choice_id": "C111111111",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:20:00+02:00",
        "user": null,
        "poll_id": "P123456789",
        "choice_id": "C333333333",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:40:00+02:00",
        "user": null,
        "poll_id": "P123456789",
        "choice_id": "C333333333",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:40:00+02:00",
        "user": null,
        "poll_id": "P123456789",
        "choice_id": "C222222222",
        "rank": 2
    }
    ]

Vous avez maintenant tous les éléments pour vous lancer !

Profitez d’AgorAPI, et n’hésitez pas à nous contacter en cas de difficultés, ou si vous avez une suggestion à nous faire.

Guides et documentation de AgorAPI

Doc exécutable

Pour plus de détails sur le fonctionnement de AgorAPI, vous pouvez consulter la documentation exhaustive, entièrement exécutable.

Les appels cURL générés par la documentation sont également indiqués, pour faciliter l’interaction en ligne de commande.

Screenshot of Open Agora in Slack