Une solution de stockage
libre, générique et réutilisable
Il était une fois
Alice
Elle conçoit des applications
Elle a plein d'idées
Genre, vraiment
Du coup elle fait plein d'applis :)
Et la même question revient à chaque fois...
Où et comment je stocke les données ?
Comment je les synchronise ?
Du coup, à chaque fois...
<?php
class NewNewServer extends AbstractServerFactory {
// mais pourquoi...
}
Alors elle se dit...
je vais utiliser un silo
Mais se posent alors d'autres questions...
- Est-ce que le silo lit les données de mon application, de ses utilisateurs ?
- Ils font quoi avec ?
- Peuvent-ils me censurer, les censurer ?
- Et niveau surveillance ?
- Et si le service ferme ?
Kinto tente d'apporter une solution générique à l'ensemble de ces problèmes
Généricité
Généricité
- HTTP
- JSON
- REST
Des concepts
et une API simples
/buckets
/buckets/todoapp
/buckets/todoapp/collections
/buckets/todoapp/collections/tasks
/buckets/todoapp/collections/tasks/records
/buckets/todoapp/collections/tasks/records/42
bucket / collection / record
$ http -a alice: :8888/v1/buckets
HTTP/1.1 200 OK
Total-Records: 0
{
"data": []
}
Lister les buckets
$ http -a alice: PUT :8888/v1/buckets/todoapp
HTTP/1.1 201 Created
{
"data": {
"id": "todoapp",
"last_modified": 1479479506138
},
"permissions": {
"write": [
"basicauth:ca3731c2b1028da61b4babd187abf3341aa394cbd6c1ec5d5817c41806bab5be"
]
}
}
Créer un bucket
$ http -a alice: GET :8888/v1/buckets
HTTP/1.1 200 OK
Total-Records: 1
{
"data": [
{
"id": "todoapp",
"last_modified": 1479479506138
}
]
}
Lister les buckets à nouveau
http -a alice: PUT :8888/v1/buckets/todoapp/collections/tasks
HTTP/1.1 201 Created
{
"data": {
"id": "tasks",
"last_modified": 1479479628933
},
"permissions": {
"write": [
"basicauth:ca3731c2b1028da61b4babd187abf3341aa394cbd6c1ec5d5817c41806bab5be"
]
}
}
Créer une collection
$ echo '{"data": {"title": "Slides kinto", "done": false}}' | \
http -a alice: POST :8888/v1/buckets/todoapp/collections/tasks/records
HTTP/1.1 201 Created
{
"data": {
"done": false,
"id": "b4b842ea-a8d1-4c46-baec-efe53cedf8d4",
"last_modified": 1479479773800,
"title": "Slides kinto"
},
"permissions": {
"write": [
"basicauth:ca3731c2b1028da61b4babd187abf3341aa394cbd6c1ec5d5817c41806bab5be"
]
}
}
Créer un record
$ echo '{"data": {"title": "Procrastiner un peu", "done": true}}' | \
http -a alice: POST :8888/v1/buckets/todoapp/collections/tasks/records
HTTP/1.1 201 Created
{
"data": {
"done": true,
"id": "8fbd9559-32fe-4f92-94d2-cd963dbad529",
"last_modified": 1479480043970,
"title": "Procrastiner un peu"
},
"permissions": {
"write": [
"basicauth:ca3731c2b1028da61b4babd187abf3341aa394cbd6c1ec5d5817c41806bab5be"
]
}
}
Créer un autre record
$ http -a alice: :8888/v1/buckets/todoapp/collections/tasks/records
HTTP/1.1 200 OK
Total-Records: 2
{
"data": [
{
"done": true,
"id": "8fbd9559-32fe-4f92-94d2-cd963dbad529",
"last_modified": 1479480043970,
"title": "Procrastiner un peu"
},
{
"done": false,
"id": "b4b842ea-a8d1-4c46-baec-efe53cedf8d4",
"last_modified": 1479479773800,
"title": "Slides kinto"
}
]
}
Lister les records
$ http -a alice: :8888/v1/buckets/todoapp/collections/tasks/records?done=true
HTTP/1.1 200 OK
Total-Records: 1
{
"data": [
{
"done": true,
"id": "8fbd9559-32fe-4f92-94d2-cd963dbad529",
"last_modified": 1479480043970,
"title": "Procrastiner un peu"
}
]
}
Filtrer les records
import KintoClient from "kinto-http"
const client = new KintoClient("https://kinto.dev.mozaws.net/v1/")
demo();
async function demo() {
await client.createBucket("todoapp")
const bucket = client.bucket("todoapp")
await bucket.createCollection("tasks")
const collection = bucket.collection("tasks")
await collection.createRecord({title: "Slides kinto", done: false})
await collection.createRecord({title: "Procrastiner un peu", done: true})
console.log(await collection.listRecords())
console.log(await collection.listRecords({filters: {done: true}}))
}
La même chose en JavaScript (kinto-http.js)
Généricité
- Une nouvelle idée d'application ?
- Hop, un nouveau bucket
- La stack techno reste la même...
- ... et le serveur est déjà déployé :)
Généricité
- Et pour administrer l'ensemble des données applicatives
- kinto-admin
kinto-admin
Synchronisation
Synchronisation
- Protocole de synchronisation simple
- basé sur les timestamps
- kinto.js, offline first client for Kinto
import Kinto from "kinto"
const tasks = new Kinto({
remote: "https://kinto.dev.mozaws.net/v1",
bucket: "todoapp",
}).collection("tasks");
await tasks.create({label: "Try Kinto.js", done: true})
const result = await tasks.sync()
if (result.conflicts.length > 0) {
console.warn("Uh oh, conflicts encountered!")
await tasks.sync({strategy: "SERVER_WINS"})
}
Confidentialité
- Chiffrement des données de bout en bout avec kinto.js
- Quelqu'un met la main sur ses données ? Il ne peut rien en faire !
Auto-hébergement
- Python, postgresql
- Docker
- Hébergeurs
- Heroku
- AlwaysData