13 KiB
Project Notes REST API Documentation
Version: v1
Base URL: http://localhost:8080/api/v1
Table des matières
- Vue d'ensemble
- Authentification
- Formats de données
- Endpoints
- Codes de statut HTTP
- Exemples d'utilisation
Vue d'ensemble
L'API REST de Project Notes permet de gérer vos notes Markdown via HTTP. Elle supporte :
- Listage : Récupérer la liste de toutes les notes avec métadonnées
- Lecture : Télécharger une note en JSON ou Markdown brut
- Écriture : Créer ou mettre à jour une note
- Suppression : Supprimer une note définitivement
Caractéristiques
- ✅ Versionnée :
/api/v1pour assurer la compatibilité future - ✅ Content Negotiation : Support JSON et Markdown selon le header
Accept - ✅ Idempotence : PUT crée ou met à jour (idempotent)
- ✅ Automatisation : Front matter géré automatiquement
- ✅ Ré-indexation : Recherche mise à jour automatiquement après chaque modification
- ✅ Support sous-dossiers : Organisation hiérarchique native
Authentification
Version actuelle : Aucune authentification requise
⚠️ IMPORTANT : L'API n'a pas d'authentification. Si vous exposez le serveur publiquement :
- Utilisez un reverse proxy (nginx, Caddy) avec authentification
- Implémentez Basic Auth ou API Key
- Utilisez un VPN ou tunnel SSH
Formats de données
Note complète (NoteResponse)
{
"path": "projet/backend.md",
"title": "Backend API",
"content": "---\ntitle: Backend API\n...\n---\n\n# Content",
"body": "\n# Content",
"frontMatter": {
"title": "Backend API",
"date": "10-11-2025",
"last_modified": "10-11-2025:14:30",
"tags": ["projet", "backend"]
},
"lastModified": "10-11-2025:14:30",
"size": 1024
}
Métadonnées de note (NoteMetadata)
{
"path": "projet/backend.md",
"title": "Backend API",
"tags": ["projet", "backend"],
"lastModified": "10-11-2025:14:30",
"date": "10-11-2025",
"size": 1024
}
Requête de création/modification (NoteRequest)
Deux options :
Option 1 : Content complet (recommandé pour migration)
{
"content": "---\ntitle: Ma note\ntags: [test]\n---\n\n# Contenu"
}
Option 2 : Body + FrontMatter séparés (recommandé pour création)
{
"body": "\n# Mon contenu\n\nTexte ici...",
"frontMatter": {
"title": "Ma note",
"tags": ["test", "exemple"]
}
}
Erreur (ErrorResponse)
{
"error": "Bad Request",
"message": "Invalid path",
"code": 400
}
Endpoints
Lister les notes
Récupère la liste de toutes les notes avec leurs métadonnées.
Endpoint : GET /api/v1/notes
Paramètres : Aucun
Réponse : 200 OK
{
"notes": [
{
"path": "projet/backend.md",
"title": "Backend API",
"tags": ["projet", "backend"],
"lastModified": "10-11-2025:14:30",
"date": "10-11-2025",
"size": 1024
},
{
"path": "daily/2025-11-10.md",
"title": "Notes du 10 novembre",
"tags": ["daily"],
"lastModified": "10-11-2025:09:15",
"date": "10-11-2025",
"size": 2048
}
],
"total": 2
}
Exemple curl :
curl http://localhost:8080/api/v1/notes
Récupérer une note
Télécharge une note spécifique. Le format dépend du header Accept.
Endpoint : GET /api/v1/notes/{path}
Paramètres :
{path}: Chemin relatif de la note (ex:projet/backend.md)
Headers :
Accept: application/json(défaut) : Retourne JSON avec métadonnéesAccept: text/markdown: Retourne Markdown brutAccept: text/plain: Retourne Markdown brut
Réponse JSON : 200 OK
{
"path": "projet/backend.md",
"title": "Backend API",
"content": "---\ntitle: Backend API\ndate: 10-11-2025\nlast_modified: 10-11-2025:14:30\ntags:\n - projet\n - backend\n---\n\n# Backend API\n\nContenu de la note...",
"body": "\n# Backend API\n\nContenu de la note...",
"frontMatter": {
"title": "Backend API",
"date": "10-11-2025",
"last_modified": "10-11-2025:14:30",
"tags": ["projet", "backend"]
},
"lastModified": "10-11-2025:14:30",
"size": 1024
}
Réponse Markdown : 200 OK
---
title: Backend API
date: 10-11-2025
last_modified: 10-11-2025:14:30
tags:
- projet
- backend
---
# Backend API
Contenu de la note...
Erreurs :
404 Not Found: Note inexistante
Exemples curl :
# Récupérer en JSON
curl http://localhost:8080/api/v1/notes/projet/backend.md \
-H "Accept: application/json"
# Récupérer en Markdown brut
curl http://localhost:8080/api/v1/notes/projet/backend.md \
-H "Accept: text/markdown"
# Sauvegarder dans un fichier
curl http://localhost:8080/api/v1/notes/projet/backend.md \
-H "Accept: text/markdown" \
-o backend.md
Créer/Mettre à jour une note
Crée une nouvelle note ou met à jour une note existante (idempotent).
Endpoint : PUT /api/v1/notes/{path}
Paramètres :
{path}: Chemin relatif de la note (ex:projet/nouvelle-note.md)
Headers :
Content-Type: application/json: Envoyer du JSONContent-Type: text/markdown: Envoyer du Markdown brut
Body JSON :
{
"body": "\n# Ma nouvelle note\n\nContenu ici...",
"frontMatter": {
"title": "Ma nouvelle note",
"tags": ["test", "exemple"]
}
}
Ou avec content complet :
{
"content": "---\ntitle: Ma note\ntags: [test]\n---\n\n# Contenu"
}
Body Markdown brut :
# Ma nouvelle note
Contenu ici...
Réponse : 201 Created (nouvelle note) ou 200 OK (mise à jour)
{
"path": "projet/nouvelle-note.md",
"title": "Ma nouvelle note",
"content": "---\ntitle: Ma nouvelle note\n...",
"body": "\n# Ma nouvelle note\n\nContenu ici...",
"frontMatter": {
"title": "Ma nouvelle note",
"date": "10-11-2025",
"last_modified": "10-11-2025:14:35",
"tags": ["test", "exemple"]
},
"lastModified": "10-11-2025:14:35",
"size": 256
}
Comportement :
- ✅ Crée automatiquement les dossiers parents
- ✅ Génère le front matter si absent
- ✅ Met à jour
last_modifiedautomatiquement - ✅ Préserve
datepour notes existantes - ✅ Ré-indexe automatiquement pour la recherche
Erreurs :
400 Bad Request: Chemin invalide ou JSON malformé415 Unsupported Media Type: Content-Type non supporté500 Internal Server Error: Erreur d'écriture
Exemples curl :
# Créer avec JSON
curl -X PUT http://localhost:8080/api/v1/notes/projet/test.md \
-H "Content-Type: application/json" \
-d '{
"body": "\n# Test\n\nCeci est un test.",
"frontMatter": {
"title": "Note de test",
"tags": ["test"]
}
}'
# Créer avec Markdown brut
curl -X PUT http://localhost:8080/api/v1/notes/projet/simple.md \
-H "Content-Type: text/markdown" \
-d "# Simple note
Contenu simple sans front matter."
# Upload depuis un fichier
curl -X PUT http://localhost:8080/api/v1/notes/projet/from-file.md \
-H "Content-Type: text/markdown" \
--data-binary @local-file.md
Supprimer une note
Supprime définitivement une note.
Endpoint : DELETE /api/v1/notes/{path}
Paramètres :
{path}: Chemin relatif de la note (ex:projet/old-note.md)
Réponse : 200 OK
{
"message": "Note deleted successfully",
"path": "projet/old-note.md"
}
Erreurs :
404 Not Found: Note inexistante500 Internal Server Error: Erreur de suppression
Exemple curl :
curl -X DELETE http://localhost:8080/api/v1/notes/projet/old-note.md
Codes de statut HTTP
| Code | Signification | Description |
|---|---|---|
200 |
OK | Requête réussie |
201 |
Created | Note créée avec succès |
400 |
Bad Request | Requête invalide (chemin, JSON, etc.) |
404 |
Not Found | Note inexistante |
405 |
Method Not Allowed | Méthode HTTP non supportée |
415 |
Unsupported Media Type | Content-Type non supporté |
500 |
Internal Server Error | Erreur serveur |
Exemples d'utilisation
Synchronisation de notes
Télécharger toutes les notes :
#!/bin/bash
# Télécharger toutes les notes localement
mkdir -p notes-backup
# Récupérer la liste
curl -s http://localhost:8080/api/v1/notes | jq -r '.notes[].path' | while read path; do
# Créer les dossiers parents
mkdir -p "notes-backup/$(dirname "$path")"
# Télécharger la note
curl -s http://localhost:8080/api/v1/notes/"$path" \
-H "Accept: text/markdown" \
-o "notes-backup/$path"
echo "✓ Downloaded: $path"
done
echo "Backup terminé!"
Uploader un dossier de notes :
#!/bin/bash
# Uploader toutes les notes .md d'un dossier
find ./my-notes -name "*.md" | while read file; do
# Calculer le chemin relatif
relpath="${file#./my-notes/}"
# Upload
curl -X PUT http://localhost:8080/api/v1/notes/"$relpath" \
-H "Content-Type: text/markdown" \
--data-binary @"$file"
echo "✓ Uploaded: $relpath"
done
echo "Upload terminé!"
Recherche et filtrage
Lister toutes les notes avec un tag spécifique :
curl -s http://localhost:8080/api/v1/notes | \
jq '.notes[] | select(.tags | contains(["projet"])) | .path'
Compter les notes par dossier :
curl -s http://localhost:8080/api/v1/notes | \
jq -r '.notes[].path' | \
xargs -n1 dirname | \
sort | uniq -c
Création automatique de notes
Note quotidienne :
#!/bin/bash
# Créer une note quotidienne
TODAY=$(date +%Y-%m-%d)
TITLE="Notes du $(date +%d/%m/%Y)"
curl -X PUT http://localhost:8080/api/v1/notes/daily/${TODAY}.md \
-H "Content-Type: application/json" \
-d "{
\"body\": \"\\n# ${TITLE}\\n\\n## Tasks\\n- [ ] TODO\\n\\n## Notes\\n\",
\"frontMatter\": {
\"title\": \"${TITLE}\",
\"tags\": [\"daily\"]
}
}"
echo "Note quotidienne créée: daily/${TODAY}.md"
Intégration avec d'autres outils
Exporter en HTML avec Pandoc :
curl -s http://localhost:8080/api/v1/notes/projet/doc.md \
-H "Accept: text/markdown" | \
pandoc -f markdown -t html -o doc.html
echo "Exporté en HTML: doc.html"
Recherche full-text avec jq :
# Chercher "API" dans tous les titres
curl -s http://localhost:8080/api/v1/notes | \
jq '.notes[] | select(.title | contains("API"))'
Script de maintenance
Vérifier les notes sans tags :
curl -s http://localhost:8080/api/v1/notes | \
jq -r '.notes[] | select(.tags | length == 0) | .path'
Statistiques :
#!/bin/bash
# Afficher des statistiques sur les notes
STATS=$(curl -s http://localhost:8080/api/v1/notes)
TOTAL=$(echo "$STATS" | jq '.total')
TOTAL_SIZE=$(echo "$STATS" | jq '[.notes[].size] | add')
AVG_SIZE=$(echo "$STATS" | jq '[.notes[].size] | add / length | floor')
echo "📊 Statistiques des notes"
echo "========================"
echo "Total de notes: $TOTAL"
echo "Taille totale: $(numfmt --to=iec-i --suffix=B $TOTAL_SIZE)"
echo "Taille moyenne: $(numfmt --to=iec-i --suffix=B $AVG_SIZE)"
echo ""
echo "Top 5 tags:"
echo "$STATS" | jq -r '.notes[].tags[]' | sort | uniq -c | sort -rn | head -5
Bonnes pratiques
Sécurité
- Ne pas exposer publiquement sans authentification
- Utiliser HTTPS en production
- Valider les chemins côté client (éviter
../malveillants) - Limiter la taille des uploads (si nécessaire, ajouter un middleware)
Performance
- Pagination : L'API liste ne pagine pas actuellement (toutes les notes en une requête). Pour beaucoup de notes (>1000), envisager d'ajouter
?limit=et?offset= - Cache : Utiliser un proxy cache (Varnish, nginx) pour GET
- Compression : Activer gzip sur le reverse proxy
Workflow recommandé
- Backup régulier : Script cron qui télécharge toutes les notes
- Versioning Git : Synchroniser le dossier de notes avec Git
- CI/CD : Valider le format Markdown avec des linters
- Monitoring : Logger les accès API pour audit
Support et contribution
- Issues : Rapporter les bugs sur GitHub
- Documentation : Ce fichier (
API.md) - Code source :
internal/api/rest_handler.go
Changelog
v1 (2025-11-10)
- ✨ Première version de l'API REST
- ✅ Endpoints: LIST, GET, PUT, DELETE
- ✅ Content negotiation JSON/Markdown
- ✅ Support sous-dossiers
- ✅ Gestion automatique du front matter
- ✅ Ré-indexation automatique
Note : Cette API coexiste avec l'interface web HTML. Les deux peuvent être utilisées simultanément sans conflit.