API PocketBase : Tutoriel CRUD Complet Records & Collections 2026
PocketBase génère automatiquement une API REST pour gérer vos données. Cela signifie que dès que vous créez une collection, vous avez accès à des endpoints prêts à l'emploi pour lire, créer, mettre à jour et supprimer des enregistrements. C'est idéal pour les petites entreprises ou startups qui veulent un backend simple sans passer des heures à coder des routes personnalisées. Dans ce tutoriel, nous couvrons les endpoints pour les records (les données individuelles) et les collections (les structures de données), avec des exemples concrets en cURL et via les SDK officiels. Tout est basé sur la documentation officielle de PocketBase en 2025.
Nous supposons que vous avez déjà installé PocketBase et lancé un serveur local sur http://127.0.0.1:8090. Si ce n'est pas le cas, consultez notre guide d'introduction. Pour tester, utilisez un outil comme Postman ou votre terminal. L'authentification se fait via un token JWT dans l'en-tête Authorization: <token>, mais elle dépend des règles de vos collections.
1. Endpoints CRUD pour les Records
Les records sont les lignes de données dans une collection. L'API fournit des opérations CRUD complètes : Create (créer), Read (lire), Update (mettre à jour), Delete (supprimer). Tous les endpoints sont sous /api/collections/<nom-collection>/records. L'authentification est contrôlée par les règles de la collection (par exemple, listRule pour la lecture).
Lister les Records (Read - GET)
Pour récupérer une liste de records, utilisez GET /api/collections/<collection>/records. C'est paginé par défaut (30 items par page).
Paramètres principaux :
page: Numéro de page (défaut : 1).perPage: Nombre d'items par page (défaut : 30, max : 200).sort: Tri, par exemple-createdpour descendant sur la date de création, ou+titlepour ascendant.filter: Expression pour filtrer, commetitle ~ "test" && created > "2025-01-01". Les opérateurs incluent=,!=,>,~(LIKE),&&,||, et des parenthèses pour grouper.expand: Étendre les relations, par exemplerelField1,relField2.subField(jusqu'à 6 niveaux).fields: Champs à inclure, par exempleid,title,createdou*pour tout.
Exemple en cURL (lister les posts d'une collection "posts") :
curl "http://127.0.0.1:8090/api/collections/posts/records?page=1&perPage=5&sort=-created&filter=title~'2025'&expand=author" \
-H "Authorization: YOUR_TOKEN"
Réponse JSON typique :
{
"page": 1,
"perPage": 5,
"totalItems": 10,
"totalPages": 2,
"items": [
{
"id": "RECORD123",
"collectionId": "posts_id",
"collectionName": "posts",
"updated": "2025-11-15 10:00:00.000Z",
"created": "2025-11-10 09:00:00.000Z",
"title": "Mon premier post 2025",
"content": "Contenu ici...",
"expand": {
"author": {
"id": "AUTHOR456",
"name": "John Doe"
}
}
}
]
}
Avec le SDK JavaScript :
import PocketBase from 'pocketbase';
const pb = new PocketBase('http://127.0.0.1:8090');
const result = await pb.collection('posts').getList(1, 5, {
sort: '-created',
filter: 'title ~ "2025"',
expand: 'author'
});
console.log(result.items);
Pour Dart (Flutter) :
import 'package:pocketbase/pocketbase.dart';
final pb = PocketBase('http://127.0.0.1:8090');
final result = await pb.collection('posts').getList(
page: 1,
perPage: 5,
sort: '-created',
filter: 'title ~ "2025"',
expand: 'author',
);
print(result.items);
Voir un Record Spécifique (Read - GET)
Pour un record unique : GET /api/collections/<collection>/records/<id>.
Paramètres : expand et fields comme pour la liste.
Exemple en cURL :
curl "http://127.0.0.1:8090/api/collections/posts/records/RECORD123?expand=author&fields=id,title,content" \
-H "Authorization: YOUR_TOKEN"
Réponse :
{
"id": "RECORD123",
"collectionId": "posts_id",
"collectionName": "posts",
"updated": "2025-11-15 10:00:00.000Z",
"created": "2025-11-10 09:00:00.000Z",
"title": "Mon premier post 2025",
"content": "Contenu ici...",
"expand": {
"author": { "id": "AUTHOR456", "name": "John Doe" }
}
}
SDK JS :
const record = await pb.collection('posts').getOne('RECORD123', { expand: 'author' });
Créer un Record (Create - POST)
POST /api/collections/<collection>/records. Envoyez le body en JSON ou multipart pour les fichiers.
Body : Les champs de la collection. Pour une collection auth, incluez password et passwordConfirm.
Exemple en cURL (JSON) :
curl -X POST "http://127.0.0.1:8090/api/collections/posts/records" \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_TOKEN" \
-d '{
"title": "Nouveau post",
"content": "Contenu du post",
"author": "AUTHOR456"
}'
Réponse :
{
"id": "NEWRECORD789",
"collectionId": "posts_id",
"collectionName": "posts",
"updated": "2025-11-30 14:00:00.000Z",
"created": "2025-11-30 14:00:00.000Z",
"title": "Nouveau post",
"content": "Contenu du post",
"author": "AUTHOR456"
}
Pour un fichier (multipart) :
curl -X POST "http://127.0.0.1:8090/api/collections/posts/records" \
-F "title=Nouveau post avec image" \
-F "image=@/path/to/image.jpg" \
-H "Authorization: YOUR_TOKEN"
SDK JS :
const newRecord = await pb.collection('posts').create({
title: 'Nouveau post',
content: 'Contenu du post',
author: 'AUTHOR456'
});
Mettre à Jour un Record (Update - PATCH)
PATCH /api/collections/<collection>/records/<id>. Mettez à jour seulement les champs fournis.
Exemple en cURL :
curl -X PATCH "http://127.0.0.1:8090/api/collections/posts/records/RECORD123" \
-H "Content-Type: application/json" \
-H "Authorization: YOUR_TOKEN" \
-d '{
"title": "Post mis à jour",
"content": "Nouveau contenu"
}'
Pour changer un mot de passe dans une collection auth, ajoutez oldPassword.
SDK JS :
await pb.collection('posts').update('RECORD123', {
title: 'Post mis à jour',
content: 'Nouveau contenu'
});
Supprimer un Record (Delete - DELETE)
DELETE /api/collections/<collection>/records/<id>.
Exemple en cURL :
curl -X DELETE "http://127.0.0.1:8090/api/collections/posts/records/RECORD123" \
-H "Authorization: YOUR_TOKEN"
Réponse : 204 No Content.
SDK JS :
await pb.collection('posts').delete('RECORD123');
2. Pagination, Tri, Filtrage et Expansion
Ces fonctionnalités rendent l'API puissante pour les apps scalables.
Pagination
Utilisez page et perPage pour diviser les résultats. Pour tout charger sans pagination :
- SDK JS :
getFullList({ sort: '-created' }). - Ajoutez
skipTotal: truepour éviter le comptage total (utile pour de grandes listes).
Exemple : Charger 100 premiers sans total :
curl "http://127.0.0.1:8090/api/collections/posts/records?perPage=100&skipTotal=true"
Tri (Sort)
sort=-created trie par date descendante. Options : champs personnalisés, @random pour aléatoire, @rowid pour l'ordre d'insertion.
Exemple SDK :
await pb.collection('posts').getList(1, 10, { sort: '+title,-created' });
Filtrage (Filter)
Expressions flexibles. Exemples :
status = "published".(age > 18 && city ~ "Paris") || country = "France".- Pour relations :
relField.id = "ID123".
Testez dans l'admin UI de PocketBase pour valider.
Exemple :
const filtered = await pb.collection('users').getList(1, 20, {
filter: 'email ~ "gmail.com" && created >= "2025-01-01"'
});
Expansion (Expand)
Chargez les données liées sans requêtes multiples. Limité à 6 niveaux, vérifié par permissions.
Exemple pour un post avec auteur et commentaires :
?expand=author,comments.author
SDK :
await pb.collection('posts').getOne('RECORD123', { expand: 'author,comments' });
3. Import et Export JSON
Pour les Records
Pas d'endpoint direct pour exporter, mais utilisez la liste avec getFullList pour tout récupérer en JSON.
Pour importer en masse : Utilisez l'endpoint batch (voir ci-dessous) ou l'import via l'admin UI. Pour du code, bouclez sur create ou utilisez batch pour des transactions atomiques.
Exemple d'export via SDK (tout en JSON) :
const allRecords = await pb.collection('posts').getFullList();
console.log(JSON.stringify(allRecords, null, 2)); // Copiez ce JSON
Pour importer plusieurs :
Utilisez batch (section suivante).
Pour les Collections
Endpoint dédié pour importer des configurations de collections : PUT /api/collections/import (superuser only).
Body :
{
"collections": [
{
"name": "posts",
"type": "base",
"fields": [
{ "name": "title", "type": "text", "required": true },
{ "name": "content", "type": "editor" }
],
"listRule": "",
"viewRule": "",
"createRule": "",
"updateRule": "",
"deleteRule": ""
}
],
"deleteMissing": false
}
Exemple en cURL :
curl -X PUT "http://127.0.0.1:8090/api/collections/import" \
-H "Authorization: SUPERUSER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"collections": [...], "deleteMissing": false}'
Pas d'export direct, mais récupérez via GET /api/collections et formatez en JSON.
SDK JS pour import :
await pb.collections.import([
{
name: 'posts',
type: 'base',
fields: [{ name: 'title', type: 'text', required: true }]
}
], false);
Pour les startups, c'est parfait pour migrer des schémas entre environnements dev/prod.
4. Gestion des Erreurs
PocketBase renvoie des erreurs HTTP standard avec un body JSON structuré :
{
"code": 400,
"message": "Failed to parse filter expression.",
"data": {
"filter": {
"code": 400,
"message": "Unexpected token."
}
}
}
Erreurs courantes :
- 400 Bad Request : Validation échouée (champs manquants, filter invalide), ou batch mal formé.
- 401 Unauthorized : Token manquant ou expiré.
- 403 Forbidden : Pas de permission (règles de collection non respectées).
- 404 Not Found : Collection ou record inexistant.
- 429 Too Many Requests : Rate limit (configurable dans settings).
Toujours vérifiez le data pour des détails. Dans le SDK, les erreurs sont des objets PbError avec status, message, data.
Exemple de gestion en JS :
try {
const record = await pb.collection('posts').create({ title: '' }); // Manque required
} catch (error) {
if (error.status === 400) {
console.log('Validation échouée:', error.data);
}
}
Pour les SMB, loggez ces erreurs pour monitorer les problèmes d'API.
5. Exemples cURL et SDK
Nous avons vu des exemples ci-dessus. Pour batch (opérations groupées, transactionnelles) : Activez-le dans Settings > Application.
Exemple batch en cURL (créer et updater) :
curl -X POST "http://127.0.0.1:8090/api/batch" \
-H "Authorization: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"requests": [
{
"method": "POST",
"url": "/api/collections/posts/records",
"body": { "title": "Post 1" }
},
{
"method": "PATCH",
"url": "/api/collections/posts/records/RECORD123",
"body": { "title": "Post mis à jour" }
},
{
"method": "DELETE",
"url": "/api/collections/posts/records/OLDRECORD"
}
]
}'
Réponse : Tableau des résultats par requête.
SDK JS pour batch :
const batchResult = await pb.sendBatch([
{ method: 'POST', url: '/api/collections/posts/records', body: { title: 'Post 1' } },
{ method: 'PATCH', url: '/api/collections/posts/records/RECORD123', body: { title: 'Updated' } }
]);
6. Endpoints CRUD pour les Collections
Ces endpoints gèrent les structures elles-mêmes (superuser only). Base URL : /api/collections.
Lister les Collections (GET /api/collections)
Paginer et filtrer comme pour records.
Exemple cURL :
curl "http://127.0.0.1:8090/api/collections?page=1&perPage=10&sort=-created" \
-H "Authorization: SUPERUSER_TOKEN"
Réponse : Liste avec items contenant id, name, type, fields, etc.
SDK :
const collections = await pb.collections.getList(1, 10);
Voir une Collection (GET /api/collections/)
Exemple :
curl "http://127.0.0.1:8090/api/collections/posts?fields=name,type,fields" \
-H "Authorization: SUPERUSER_TOKEN"
Créer une Collection (POST /api/collections)
Body : Nom, type (base/auth/view), fields, rules.
Exemple cURL :
curl -X POST "http://127.0.0.1:8090/api/collections" \
-H "Authorization: SUPERUSER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "users",
"type": "auth",
"fields": [
{ "name": "name", "type": "text", "required": true }
]
}'
SDK :
await pb.collections.create({
name: 'users',
type: 'auth',
fields: [{ name: 'name', type: 'text', required: true }]
});
Mettre à Jour (PATCH /api/collections/)
Similaire à create, mais pour modifier.
Exemple :
await pb.collections.update('posts', {
listRule: '@request.auth.id != ""',
fields: [...nouveaux champs]
});
Supprimer (DELETE /api/collections/)
Supprime la collection et ses records (attention !).
Exemple :
curl -X DELETE "http://127.0.0.1:8090/api/collections/test" \
-H "Authorization: SUPERUSER_TOKEN"
Autres : DELETE /api/collections/<name>/truncate pour vider sans supprimer la structure.
Intégration avec Frontend et Mobile
Pour React/Vue : Utilisez le SDK JS pour des appels asynchrones. Exemple dans un composant :
useEffect(() => {
const fetchPosts = async () => {
const posts = await pb.collection('posts').getFullList({ sort: '-created' });
setPosts(posts);
};
fetchPosts();
}, []);
Pour Flutter : Le SDK Dart gère l'auth et les realtime subscriptions.
En production, gérez les tokens avec localStorage ou secure storage. Pour les startups, commencez avec des règles simples et raffinez au fur et à mesure.
Cette API automatique fait de PocketBase un choix rapide pour prototyper. Testez ces endpoints et passez à l'auth ou realtime ensuite. 1win spaceman