tp6 node
This commit is contained in:
parent
835598801e
commit
506ecfa837
R4.01_R4.A.10
@ -15,5 +15,9 @@
|
||||
#### Semaine 5
|
||||
[API REST](cours/api.pdf), service firebase [tp5](./td_tp/tp5)
|
||||
|
||||
#### Semaine 6
|
||||
[Nodejs](cours/nodejs.pdf) et api de données, [tp7](./td_tp/tp6)
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
R4.01_R4.A.10/cours/nodejs.pdf
Normal file
BIN
R4.01_R4.A.10/cours/nodejs.pdf
Normal file
Binary file not shown.
109
R4.01_R4.A.10/td_tp/tp6/README.md
Normal file
109
R4.01_R4.A.10/td_tp/tp6/README.md
Normal file
@ -0,0 +1,109 @@
|
||||
# TP javascript : Nodejs
|
||||
#### Configuration
|
||||
|
||||
À l'aide de la commande `npm`, installez le module `express` dont on aura besoin pour la suite.
|
||||
|
||||
npm install express
|
||||
|
||||
L'installation des modules se fait dans le repertoire `ǹode_modules`. C'est
|
||||
là que `node` va les chercher par défaut.
|
||||
|
||||
Vous pouvez les installer à un autre endroit (option `--prefix` de `npm` et variable d'environnement
|
||||
`ǸODE_PATH` pour `ǹode`)
|
||||
|
||||
Testez votre installation avec un serveur http minimaliste : `ǹode app.js`
|
||||
|
||||
```js
|
||||
// app.js
|
||||
|
||||
const http = require('http');
|
||||
|
||||
const port = 3000;
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
res.statusCode = 200;
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
res.end('Hello World');
|
||||
});
|
||||
|
||||
server.listen(port, () => {
|
||||
console.log(`Server running at *:${port}/`);
|
||||
});
|
||||
```
|
||||
|
||||
#### Ex1
|
||||
Un serveur web pour notre application todolist.
|
||||
|
||||
On va utiliser pour cela le module [express](https://expressjs.com/fr/4x/api.html). `express` facilite l'écriture
|
||||
d'une application web en gérant notamment le routage et les entrées/sorties http.
|
||||
|
||||
|
||||
```js
|
||||
let express = require('express');
|
||||
let app = express();
|
||||
let todos = require('./todos.json')
|
||||
|
||||
|
||||
|
||||
app.use('/html',express.static('html'));
|
||||
app.use('/css',express.static('css'));
|
||||
app.use('/js',express.static('js'));
|
||||
app.use('/img',express.static('img'));
|
||||
app.use('/tags',express.static('tags'));
|
||||
app.use(express.json())
|
||||
```
|
||||
|
||||
- Notre serveur web possède une seule route : sa racine. Il renvoie le fichier `html/index.html`
|
||||
- `app.use` permet d'enregistrer un middleware quelconque. Une fonction exécutée quand la route d'une requête
|
||||
correspond à un path donné.
|
||||
ici, on utlise le middleware interne `express.static` qui permet de servir du contenu statique. Pour notre application,
|
||||
le contenu des repértoires `css`, `js`, `img` et `tags`.
|
||||
|
||||
L'application devrait accessible et utlisable à l'url `http://localhost:3000`. Testez.
|
||||
|
||||
On va mettre en oeuvre avec notre serveur nodejs une petite api rest pour gérer la todo-list
|
||||
|
||||
|
||||
Le serveur maintiendra lui-même cette liste
|
||||
|
||||
```js
|
||||
const todos = require('./todos.json')
|
||||
```
|
||||
|
||||
une todo est représentée par la structure suivante :
|
||||
|
||||
```js
|
||||
{ "id" : 1 , "title":"Avoid excessive caffeine","done":false }
|
||||
```
|
||||
|
||||
On va ajouter au serveur les routes suivantes :
|
||||
|
||||
| route | méthode | action |
|
||||
|---------- |:------------- |:------ |
|
||||
| /todos | GET | renvoie la todo list (tableau) |
|
||||
| /todos/:id | GET | renvoie la todo |
|
||||
| /todos | POST | ajoute une todo, et renvoie le tableau |
|
||||
| /todos | DELETE | efface un ensemble (tableau) de todo et renvoie la liste |
|
||||
| /todos/:id | DELETE | efface une todo, et renvoie la liste |
|
||||
| /todos/:id | PUT | modifie une todo, et renvoie la liste |
|
||||
|
||||
Les entrées/sorties de l'api seront formatées en JSON.
|
||||
|
||||
|
||||
Voici l'implation de la première route :
|
||||
|
||||
```js
|
||||
|
||||
let todos = require('./todos.json')
|
||||
|
||||
app.use(express.json())
|
||||
|
||||
app.get('/todos', (req,res) => {
|
||||
res.status(200).json(todos)
|
||||
})
|
||||
```
|
||||
|
||||
1. Implantez les autres routes,
|
||||
2. Testez l'api avec CURL.
|
||||
3. Branchez l'application avec cette api.
|
||||
|
9
R4.01_R4.A.10/td_tp/tp6/src/css/todo.css
Normal file
9
R4.01_R4.A.10/td_tp/tp6/src/css/todo.css
Normal file
@ -0,0 +1,9 @@
|
||||
p.todo {
|
||||
display : flex;
|
||||
justify-content : space-between;
|
||||
}
|
||||
|
||||
.done {
|
||||
text-decoration: line-through;
|
||||
color: #ccc;
|
||||
}
|
42
R4.01_R4.A.10/td_tp/tp6/src/html/index.html
Normal file
42
R4.01_R4.A.10/td_tp/tp6/src/html/index.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Riot todo</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<script src="todo.riot" type="riot"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/riot/9.4.4/riot+compiler.min.js" integrity="sha512-sMPQdAnmCCQmymthALQzoFXGFmG1hhiazFuC/8Y5hLentlAWNqs+eQQJJ/yeGC4DLk/JwLL3jGk6yoEEDNb+7w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://unpkg.com/@riotjs/route@9.2/index.umd.js"></script>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="stylesheet" href="todo.css">
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
|
||||
>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main class="container">
|
||||
<todo></todo>
|
||||
</main>
|
||||
<script type="module">
|
||||
import makeDataervice from "./js/api.js";
|
||||
|
||||
riot.register('router', route.Router);
|
||||
riot.register('route', route.Route);
|
||||
|
||||
riot.compile().then(async () => {
|
||||
let sa = makeDataervice();
|
||||
riot.install(function(component){
|
||||
component.serviceData = sa;
|
||||
})
|
||||
riot.mount('todo', {
|
||||
title: 'I want to behave!',
|
||||
todos: []
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
9
R4.01_R4.A.10/td_tp/tp6/src/js/api.js
Normal file
9
R4.01_R4.A.10/td_tp/tp6/src/js/api.js
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
export default function makeDataService(){
|
||||
let url = 'votre url';
|
||||
let service = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
return service;
|
||||
}
|
65
R4.01_R4.A.10/td_tp/tp6/src/serveur.js
Normal file
65
R4.01_R4.A.10/td_tp/tp6/src/serveur.js
Normal file
@ -0,0 +1,65 @@
|
||||
let express = require('express');
|
||||
let app = express();
|
||||
let todos = require('./todos.json')
|
||||
|
||||
|
||||
|
||||
app.use('/html',express.static('html'));
|
||||
app.use('/css',express.static('css'));
|
||||
app.use('/js',express.static('js'));
|
||||
app.use('/img',express.static('img'));
|
||||
app.use('/tags',express.static('tags'));
|
||||
app.use(express.json())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Routes
|
||||
//
|
||||
app.get('/todos', (req,res) => {
|
||||
res.status(200).json(todos)
|
||||
})
|
||||
|
||||
app.get('/todos/:id', (req,res) => {
|
||||
const id = parseInt(req.params.id)
|
||||
|
||||
// TODO
|
||||
//
|
||||
})
|
||||
|
||||
app.put('/todos/:id', (req,res) => {
|
||||
const id = parseInt(req.params.id)
|
||||
|
||||
// TODO
|
||||
//
|
||||
})
|
||||
|
||||
|
||||
app.post('/todos', (req,res) => {
|
||||
let id = todos.length > 0 ? todos[todos.length - 1].id + 1 : 1
|
||||
|
||||
// TODO
|
||||
//
|
||||
|
||||
})
|
||||
|
||||
app.delete('/todos/:id', (req,res) => {
|
||||
const id = parseInt(req.params.id)
|
||||
|
||||
// TODO
|
||||
//
|
||||
})
|
||||
|
||||
app.delete('/todos', (req,res) => {
|
||||
|
||||
// TODO
|
||||
//
|
||||
})
|
||||
|
||||
|
||||
|
||||
app.listen( 3000,()=>{
|
||||
console.log('listening on *:3000');
|
||||
})
|
||||
|
118
R4.01_R4.A.10/td_tp/tp6/src/tags/todo.riot
Normal file
118
R4.01_R4.A.10/td_tp/tp6/src/tags/todo.riot
Normal file
@ -0,0 +1,118 @@
|
||||
<todo>
|
||||
<router base = {base}>
|
||||
<route path="(#)?/:filter?"
|
||||
on-before-mount = { changeFilter }
|
||||
on-before-update = { changeFilter }
|
||||
>
|
||||
|
||||
<nav>
|
||||
<ul>
|
||||
<li>{this.state.todos.filter(todo => !todo.done).length} todos left</li>
|
||||
</ul>
|
||||
<ul>
|
||||
|
||||
<li each={filter in ['all','active','done']}>
|
||||
<!--template if = {state.filter !== filter}-->
|
||||
<a class={state.filter=== filter ? 'contrast':''} href="#/{filter}" > {filter.toUpperCase()}</a>
|
||||
<!--template>
|
||||
<template if = {state.filter === filter}>{filter.toUpperCase()}</template-->
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<article>
|
||||
<header>
|
||||
<b>{props.title}</b>
|
||||
</header>
|
||||
<template each={ todo in filterTodos() } key = {todo.id}>
|
||||
<p class="todo">
|
||||
<label class={ todo.done ? 'completed' : null }>
|
||||
<input role="switch"
|
||||
type="checkbox"
|
||||
checked={ todo.done }
|
||||
onclick={ () => toggle(todo) } />
|
||||
<span class = {todo.done ? 'done':''}> { todo.title } </span>
|
||||
</label>
|
||||
<a href="#" onclick={(e)=>remove(e,todo)}><i class="fa-solid fa-trash"></i></a>
|
||||
</p>
|
||||
<hr>
|
||||
</template>
|
||||
</article>
|
||||
<form onsubmit={ add }>
|
||||
<fieldset role="group">
|
||||
<input type="text" oninput={ edit } />
|
||||
<input type="button" disabled={ !state.text } value="Add #{ state.todos.length + 1 }">
|
||||
<input class="contrast" type="button" disabled = { !state.todos.find ( e => e.done) } onclick={ clear } value="Clear done">
|
||||
</fieldset>
|
||||
</form>
|
||||
</route>
|
||||
</router>
|
||||
<script>
|
||||
export default {
|
||||
base : 'http://localhost/~denis/RIOTJS/examples/todo-pico/',
|
||||
changeFilter(r){
|
||||
this.state.filter = r.params.filter || 'all'
|
||||
},
|
||||
async onBeforeMount(props, state) {
|
||||
// initial state
|
||||
this.state = {
|
||||
todos: props.todos,
|
||||
text: '',
|
||||
filter:'all',
|
||||
}
|
||||
let todos = await this.serviceData.getTodos()
|
||||
this.state.todos = todos;
|
||||
this.update()
|
||||
},
|
||||
// listenTodos(todos){
|
||||
// this.update({ todos : todos})
|
||||
// },
|
||||
filterTodos(){
|
||||
if (this.state.filter === 'all')
|
||||
return this.state.todos
|
||||
|
||||
if (this.state.filter === 'active')
|
||||
return this.state.todos.filter(e=> !e.done)
|
||||
|
||||
if (this.state.filter === 'done')
|
||||
return this.state.todos.filter(e=> e.done)
|
||||
},
|
||||
async remove(e,todo){
|
||||
e.preventDefault()
|
||||
let res = await this.serviceData.removeTodo(todo)
|
||||
let todos = await this.serviceData.getTodos()
|
||||
this.state.todos = todos
|
||||
this.update()
|
||||
},
|
||||
|
||||
edit(e) {
|
||||
// update only the text state
|
||||
this.update({
|
||||
text: e.target.value
|
||||
})
|
||||
},
|
||||
async clear(e) {
|
||||
|
||||
e.preventDefault()
|
||||
// console.log(this.state.todos)
|
||||
// let res = await this.serviceData.clearDone()
|
||||
// this.state.todos = this.state.todos.filter(todo => !todo.done)
|
||||
|
||||
},
|
||||
async add(e) {
|
||||
e.preventDefault()
|
||||
let text = this.state.text;
|
||||
let res = await this.serviceData.addTodo({title : text , done : false})
|
||||
let todos = await this.serviceData.getTodos()
|
||||
this.state.todos = todos
|
||||
this.update()
|
||||
},
|
||||
async toggle(todo) {
|
||||
let res = await this.serviceData.toggleTodo(todo);
|
||||
let todos = await this.serviceData.getTodos()
|
||||
this.state.todos = todos
|
||||
this.update()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</todo>
|
5
R4.01_R4.A.10/td_tp/tp6/src/todos.json
Normal file
5
R4.01_R4.A.10/td_tp/tp6/src/todos.json
Normal file
@ -0,0 +1,5 @@
|
||||
[
|
||||
{ "id":1,"title": "Avoid excessive caffeine", "done": false },
|
||||
{ "id":2,"title": "Be less provocative", "done": true },
|
||||
{ "id":3,"title": "Be nice to people", "done": true }
|
||||
]
|
Loading…
x
Reference in New Issue
Block a user