# SPARQL Protocol and RDF Query Language/Le protocole SPARQL

Dans ce chapitre, nous allons apprendre à envoyer des requêtes à une base de données qui répond à la recommandation SPARQL. Ainsi, dans les chapitres suivants, nous pourrons tester nos requêtes SPARQL immédiatement.

## Protocole HTTP

L'HyperText Transfer Protocol — littéralement « protocole de transfert hypertexte » —, plus connu sous l’abréviation HTTP, est un protocole de communication client-serveur développé pour le World Wide Web (ou W3C pour World Wide Web Consortium). HTTPS (avec S pour "secured", soit « sécurisé ») est la variante du HTTP "sécurisée" par l'usage des protocoles SSL ou TLS.
HTTP est un protocole de la couche application. Il peut fonctionner sur n’importe quelle connexion fiable. En pratique, on utilise le protocole TCP comme couche de transport. Un serveur HTTP utilise alors par défaut le port 80 (443 pour HTTPS).
Les clients HTTP les plus connus sont les navigateurs Web permettant à un utilisateur d'accéder à un serveur contenant les données. Il existe aussi des systèmes pour récupérer automatiquement le contenu d'un site, tels que les aspirateurs de site Web ou les robots d'indexation.
Ces clients se connectent à des serveurs HTTP tels qu'Apache HTTP Server, que nous installerons durant un TP.
La liaison entre le client et le serveur n’est pas toujours directe, mais, du point de vue du client HTTP, ces intermédiaires sont invisibles, à moins qu'une erreur ait lieu.

### Requêtes

Dans le protocole HTTP, une méthode est une commande spécifiant un type de requête, c'est-à-dire qu'elle demande au serveur d'effectuer une action. En général, l'action concerne une ressource identifiée. Nous allons étudier ce que l’on nomme une ressource et lister les principales commandes.

#### Ressources

Jusqu'à présent, une ressource est identifiée par une URL, qui suit le nom de la méthode HTTP. La notion d'URL a rapidement atteint ses limites et un nouveau standard est en train de le remplacer : IRI (Internationalized Resource Identifier).

##### Localisateur uniforme de ressource (URL)

Une URL (Uniform Resource Locator) est une chaîne de caractères ASCII qui spécifie où une ressource connue est disponible sur Internet et indique le mécanisme pour l'atteindre.
    http://fr.wikiversity.org est une URL pour atteindre le site fr.Wikiversity via le protocole http.
    git://github.com/BorderCloud/4store-php.git est une URL pour atteindre les sources de 4store-php via le protocole git

##### Identificateur de ressource internationalisé (IRI)

Un IRI (Internationalized Resource Identifier) est une chaîne de caractères (ASCII ou non) qui spécifie où une ressource connue est disponible sur Internet et indique le mécanisme pour l'atteindre.
La différence avec une URL est qu'un IRI peut pointer sur un contenu en utilisant la même langue que ce contenu.
http://fr.wikipedia.org (URL) pourra devenir http://fr.wikipédia.org (IRI)
Une URL est un IRI, mais un IRI n’est pas forcément une URL.
L'architecture HTTP ne supporte pas encore les IRI, mais l'implémentation est en cours. Cependant, les nouveaux logiciels comme les serveurs SPARQL ne travaillent qu'avec des IRI (et, donc, supportent les URL).

#### Commandes

Liste des principales commandes HTTP :

##### GET

    C'est la méthode la plus courante pour demander une ressource. Une requête GET est sans effet sur la ressource, il doit être possible de répéter la requête sans effet.

##### POST

    Cette méthode doit être utilisée pour soumettre des données, en vue d'un traitement, à une ressource (typiquement depuis un formulaire HTML) ; elle est souvent utilisée aussi pour la création et la mise à jour de ressources.

##### PUT

    Cette méthode permet de remplacer ou d'ajouter une ressource sur le serveur. L'URL fournie est celle de la ressource en question.

##### DELETE

    Cette méthode permet de supprimer une ressource du serveur.
Ces commandes sont souvent détournées de leur mission initiale. Par exemple, un développeur peut utiliser la méthode GET pour envoyer des informations à un serveur et pourra implémenter un traitement de mise à jour des données du serveur en cas de réception de cette commande GET.

### Codes de statut HTTP

La réponse du serveur à une commande contient le code de statut HTTP (Status code)
Voici la liste des plus courants :
| Code | Message | Signification |
| 2xx | Succès | Succès |
| 200 | OK | Requête traitée avec succès |
| 3xx | Redirection | Redirection |
| 301 | Moved Permanently | Document déplacé de façon permanente |
| 302 | Found | Document déplacé de façon temporaire |
| 303 | See Other | La réponse à cette requête est ailleurs |
| 4xx | Erreur du client | Erreur du client |
| 400 | Bad Request | La syntaxe de la requête est erronée |
| 401 | Unauthorized | Une authentification est nécessaire pour accéder à la ressource |
| 403 | Forbidden | L’authentification est refusée. Contrairement à l’erreur 401, aucune demande d’authentification ne sera faite |
| 404 | Not Found | Document non trouvé |
| 5xx | Erreur du Serveur | Erreur du Serveur |
| 500 | Internal Server Error | Erreur interne du serveur |

### Exemple de session HTTP

Voici un exemple de conversation entre un client HTTP et un serveur HTTP www.example.com via le port 80.

#### Requête

Une requête respecte un certain nombre de retours à la ligne et contient la version du protocole, ici HTTP/1.1, la commande, ici GET, la destination, ici www.example.com, et le paramètre de la commande, ici index.html.

#### Réponse

Voici la réponse que l’on obtient si tout se passe bien entre notre client et le serveur.
La réponse se compose d'un entête et du message.
L'entête se compose :

##### La première ligne donne le code de statut HTTP

    200 dans ce cas, c'est-à-dire que le serveur comprend la requête et vous transmet le résultat.

##### Date

    Moment auquel le message est généré.

##### Server

    Indique quel modèle de serveur HTTP répond à la requête.

##### Last-Modified

    Indique la date de dernière modification de la ressource.

##### ETag (entity tag)

    Numéro de version de la page dans le cache du serveur ; permet aux navigateurs Web de gérer leur mémoire cache.

##### Accept-Ranges

    Méthode pour récupérer la ressource.

##### Content-Length

    Indique la taille en octets de la ressource.

##### Content-Type

    Indique le type MIME de la ressource.
Le message contient ensuite une page HTML, mais cela dépend de la requête envoyée.
Nous allons étudier, dans la partie suivante, les différentes commandes HTTP utilisables pour un serveur SPARQL 1.0 et ses réponses.

## Protocole SPARQL
### Protocole de lecture
#### Requête
##### Adresse type d'un service SPARQL

http://IP_ou_NOM_DE_DOMAINE/sparql/
Où :
* IP_ou_NOM_DE_DOMAINE est une adresse pour atteindre le serveur
* /sparql/ est le chemin du service (cela fait partie de la recommandation)
Les services SPARQL qui utilisent de vieux logiciels, ont comme chemin : /sparql et non /sparql/

##### Paramètres d'une requête de lecture
###### query

    paramètre obligatoire, passe la requête SPARQL au service

###### default-graph-uri

    paramètre facultatif qui peut être répété, indique le ou les graphes de la base de données où exécuter la requête

###### named-graph-uri

    paramètre facultatif qui peut être répété, indique le ou les graphes qui seront utilisés au sein de la requête

###### output

    paramètre facultatif qui peut différer d'un logiciel à l'autre, si c’est une requête SELECT ou ASK, on peut demander un autre format de réponse, comme le format "json". Par défaut, le format est en XML.
Nous étudierons dans les leçons suivantes à quoi servent ces paramètres.

##### Commandes HTTP pour envoyer une requête de lecture

On peut faire une requête de lecture avec la commande GET ou POST.
La méthode GET permet d'écrire très simplement une requête (dans un navigateur pour tester une requête).
Par exemple : http://lod.bordercloud.com/sparql/?query=ask {?x ?y "TSO"@en . }
La méthode POST permet de faire les mêmes requêtes, mais POST permet d'envoyer des requêtes de taille plus importante par rapport à une requête GET.

#### Réponse

La réponse d'une requête prend la forme d'un "SPARQL result" (tableau de résultat) ou le format d'un graphe RDF.
* La forme "SPARQL result" peut prendre le format XML ou JSON (ou texte avec tabulation, en fonction des logiciels)
* La forme graphe RDF peut prendre le format XML ou Turtle.
SPARQL adapte le format de sortie en fonction du type de requêtes de lecture.
Il y a quatre types de requêtes en SPARQL (que nous étudierons en détail dans les chapitres suivants) :

##### SELECT

    retourne un SPARQL result en XML par défaut. Pour obtenir un autre format comme JSON, il faut le préciser avec le paramètre output.

##### ASK

    retourne un SPARQL result en XML par défaut. Pour obtenir un autre format comme JSON, il faut le préciser avec le paramètre output.

##### CONSTRUCT

    retourne un graphe RDF en XML par défaut. Pour obtenir un autre format comme Turtle, il faut le préciser avec le paramètre output.

##### DESCRIBE

    retourne un document en Turtle ou un graphe RDF en XML. Pour obtenir un autre format précis, il faut l'indiquer avec le paramètre output.

##### Format SPARQL result XML

Voici un exemple de requête SELECT :
Cette requête aura comme entête HTTP :
La réponse aura comme entête :
Et la réponse contiendra le document SPARQL result XML :
Voici un exemple de requête ASK :
Cette requête aura comme entête HTTP :
La réponse aura comme entête :
Et la réponse contiendra le document SPARQL result XML :

##### Format SPARQL result JSON

Voici un exemple de requête SELECT :
Cette requête aura comme entête HTTP :
ou bien pour Jena Fuseki :
La réponse aura comme entête :
Et la réponse contiendra le document JSON :
L’intérêt d'obtenir un format JSON est d’utiliser ce contenu à travers un script en Javascript. Cependant, votre navigateur n'autorise pas le chargement de JSON d'un autre domaine que celui du site où vous vous trouvez. Bien que cette limitation soit justifiée pour des raisons de sécurité, elle empêche le chargement de résultat SPARQL en JSON.
Une alternative existe : elle consiste à activer dans votre serveur l'option CORS (Cross-Origin Resource Sharing). Cette option insère la ligne Access-Control-Allow-Origin: * dans l'entête de la réponse HTTP pour désactiver cette sécurité.

##### Format graphe RDF XML

Voici un exemple de requête DESCRIBE :
Cette requête aura comme entête HTTP :
La réponse aura comme entête :
Et la réponse contiendra le document RDF XML:

##### Format graphe RDF Turtle

Voici un exemple de requête CONSTRUCT :
Cette requête aura comme entête HTTP :
La réponse aura comme entête :
Et la réponse contiendra le document turtle :

### Protocole d'écriture
#### Requête
##### Adresse type d'un service SPARQL Update

http://IP_ou_NOM_DE_DOMAINE/update/
Où :
* IP_ou_NOM_DE_DOMAINE est une adresse pour atteindre le serveur
* /update/ est le chemin du service d'écriture (cela fait partie de la recommandation)

##### Paramètres d'une requête d'écriture
###### update

    paramètre obligatoire, passe la requête SPARQL au service
Nous étudierons dans les chapitres suivants à quoi sert ce paramètre.

##### Commandes HTTP pour faire une requête d'écriture

On utilise la commande POST pour écrire des données.

#### Réponse

Pour savoir, si une requête c’est bien déroulée, on lit le code de statut HTTP, qui doit être égal à 200.
En fonction des implémentations, des messages d'erreurs peuvent être envoyés par le serveur.