Add HTTP Server

master
Denis MIGDAL 2 years ago
parent 3e8517d238
commit eb0302ee48

@ -461,7 +461,7 @@ $ELEM.dispatchEvent( CustomEvent.new($EVENT_TYPE, {"detail": $EVENT_DATA}) )
💡 Vous pouvez aussi ajouter, au 2ème argument, l'option `bubble: true` pour faire en sorte que l'événement soit bubble, i.e. se propage dans le DOM (par default `bubble: false`).
# Envoyer une requête REST
# Envoyer une requête HTTP
```javascript
// [JS] Javascript

@ -160,19 +160,166 @@ Le contenu généré peut être sous n'importe quel format : de l'HTML, des imag
## Serveur HTTP
Python (x) - Deno (Prog Web)
Un serveur HTTP répond aux *requêtes HTTP* du client par une *réponse HTTP*. Les requêtes et réponses HTTP se composent d'un *en-tête* (header) contenant les méta-données, et d'un *corps* (body) contenant les données échangées.
L'en-tête de la requête contient ainsi l'URI demandée et la *méthode HTTP*. L'en-tête de la réponse contient le *code de status* de la réponse (200 si tout c'est bien passé). Cf la section *"Envoyer une requête HTTP"* de la fiche *API JS/DOM* pour plus de détails.
Côté serveur HTTP, on manipule des routes. Une route représente un ensemble d'URI qui seront traitées par le même gestionnaire. Il peut contenir des paramètres e.g. `/dir/$PARAM/foo` qui seront exploités par le gestionnaire (handler).
Afin de rendre le code plus lisible, il est fréquent que les frameworks représentent les routes par une arborescence de fichiers. Au démarrage, le framework va ainsi lire de manière récursive un dossier e.g. `/routes/` et ajouter les différents gestionnaires en fonction des fichiers qui s'y trouvent. Ainsi, le fichiers/dossier `/routes/dir/{PARAMS}/foo` contiendra le gestionnaire à utiliser pour la route `/dir/$PARAM/foo`.
🚩 [TODO] : outils network
### Serveur HTTP (bas niveau)
```typescript
// [TS] TypeScript
// Exécuter le fichier : deno run --allow-net --allow-env $FILE
// @deno-types="npm:@types/express@4"
import express from "npm:express";
import cors from "npm:cors"
const app = express();
app.use(cors()) // CORS - Autorise l'accès à partir d'autres domaines.
// Considérer que le corps des requêtes est du texte brut.
// .raw() permet d'obtenir des données binaires.
// .json() si le corps des requêtes est systématiquement du JSON.
app.use(express.text());
// ---------------------------------------------
// ---------- ROUTES ---------------------------
// ---------------------------------------------
// Ajouter une route (méthode HTTP GET)
app.get($ROUTE, (request, response) => {
// Affiche les paramètres de la requête GET.
console.log(request.query);
response.send($DATA); // $DATA est une chaîne de charactère.
});
// Ajouter une route (méthode HTTP POST)
app.post($ROUTE, (request, response) => {
// Affiche le corps de la requête POST.
console.log(request.body);
response.send($DATA);
});
// Renvoyer du JSON dans la réponse
app.get($ROUTE, (request, response) => {
response.json($DATA); // $DATA est un object.
});
// Avec un paramètre dans la route
app.get("/dir/:param/foo", (request, response) => {
response.send(request.params.param);
});
// Retourner un code d'erreur
app.get("*", (request, response) => {
response.status(404).send("Not found");
});
// ---------------------------------------------
const port = Number(Deno.env.get("PORT")) || 3000;
app.listen(port, () => {
console.log(`Listening on http://localhost:${port}...`);
});
```
```python
# [🐍] Python
from aiohttp import web
# CORS
import aiohttp_cors
app = web.Application()
#########################################################
########### ROUTES ######################################
#########################################################
routes = web.RouteTableDef()
# Ajouter une route (méthode HTTP GET)
@routes.get($ROUTE)
async def myhandler(request):
# Affiche les paramètres de la requête GET.
print(request.rel_url.query)
return web.Response(text=$DATA) # $DATA est une chaîne de charactères.
# Ajouter une route (méthode HTTP POST)
@routes.post($ROUTE)
async def myhandler(request):
body = await request.text # pour du texte.
body = await request.json # pour du JSON.
print(body)
return web.Response(text=$DATA)
# Renvoyer du JSON dans la réponse
@routes.get($ROUTE)
async def myhandler(request):
web.json_response($DATA); # $DATA est un dictionaire.
# Avec un paramètre dans la route.
@routes.get("/dir/{param}/foo")
async def myhandler(request):
param = request.match_info.get('param', None)
print(param)
web.Response(text=$DATA)
# Retourner un code d'erreur
@routes.get("*")
async def myhandler(request):
raise web.HTTPNotFound("Not found")
# ou request.Response(text="Not found", status=404)
app.add_routes(routes)
#########################################################
# CORS - Autorise l'accès à partir d'autres domaines.
cors = aiohttp_cors.setup(app, defaults={
"*": aiohttp_cors.ResourceOptions(
allow_credentials=True,
expose_headers="*",
        allow_headers="*"
)
})
if __name__ == '__main__':
web.run_app(app)
```
### Serveur HTTP (avec arborescence de routes)
=> Requête HTTP
    => Routes (chemin)
    => body / url  
=> Serveur Python/JS/TS
## API REST
Une API REST est une manière de concevoir les échanges entre le client et le serveur de sorte à les uniformaliser, les rendre plus compréhensibles, et faciliter les opérations de tests et de déboguages.
Une API REST est une manière de concevoir les échanges HTTP entre le client et le serveur de sorte à les uniformaliser, les rendre plus compréhensibles, et faciliter les opérations de tests et de déboguages. Une API REST est donc implémentée par un serveur HTTP.
Une requête REST est composée de 3 éléments :

Loading…
Cancel
Save