quicknotes/specs/api.md

369 lines
8.2 KiB
Markdown
Raw Permalink Normal View History

# API Specification
## Overview
QuickNotes provides a RESTful API for communication between the frontend and backend. The API is built using the Gin web framework and follows REST principles.
## Base URL
All API endpoints are prefixed with `/api`.
## Authentication
The API does not currently implement authentication as it is designed for local use.
## Response Format
API responses are formatted as JSON with the following structure:
- For successful responses returning data:
```json
{
"field1": "value1",
"field2": "value2",
...
}
```
- For successful responses returning arrays:
```json
[
{
"field1": "value1",
"field2": "value2",
...
},
...
]
```
- For error responses:
```json
{
"error": "Error message"
}
```
## Status Codes
The API uses standard HTTP status codes:
- `200 OK`: The request was successful
- `400 Bad Request`: The request was invalid
- `404 Not Found`: The requested resource was not found
- `500 Internal Server Error`: An error occurred on the server
## Endpoints
### Notes
#### List Notes
- **URL**: `/api/notes`
- **Method**: `GET`
- **Description**: Get a list of all notes
- **Response**: Array of Note objects
```json
[
{
"id": "note-id",
"title": "Note Title",
"content": "Note content in Markdown",
"createdAt": "2023-01-01T12:00:00Z",
"updatedAt": "2023-01-01T12:00:00Z"
},
...
]
```
#### Create Note
- **URL**: `/api/notes`
- **Method**: `POST`
- **Description**: Create a new note
- **Request Body**: Note object without ID
```json
{
"title": "Note Title",
"content": "Note content in Markdown"
}
```
- **Response**: Created Note object with ID
```json
{
"id": "note-id",
"title": "Note Title",
"content": "Note content in Markdown",
"createdAt": "2023-01-01T12:00:00Z",
"updatedAt": "2023-01-01T12:00:00Z"
}
```
#### Get Note
- **URL**: `/api/notes/:id`
- **Method**: `GET`
- **Description**: Get a specific note by ID
- **URL Parameters**: `id` - ID of the note
- **Response**: Note object
```json
{
"id": "note-id",
"title": "Note Title",
"content": "Note content in Markdown",
"createdAt": "2023-01-01T12:00:00Z",
"updatedAt": "2023-01-01T12:00:00Z",
"linksTo": [
{
"id": "linked-note-id",
"title": "Linked Note Title"
}
],
"linkedBy": [
{
"id": "linking-note-id",
"title": "Linking Note Title"
}
]
}
```
#### Update Note
- **URL**: `/api/notes/:id`
- **Method**: `PUT`
- **Description**: Update a specific note
- **URL Parameters**: `id` - ID of the note
- **Request Body**: Note object with updated fields
```json
{
"title": "Updated Title",
"content": "Updated content"
}
```
- **Response**: Updated Note object
```json
{
"id": "note-id",
"title": "Updated Title",
"content": "Updated content",
"createdAt": "2023-01-01T12:00:00Z",
"updatedAt": "2023-01-02T12:00:00Z"
}
```
#### Delete Note
- **URL**: `/api/notes/:id`
- **Method**: `DELETE`
- **Description**: Delete a specific note
- **URL Parameters**: `id` - ID of the note
- **Response**: Empty response with status code 200
#### Import Obsidian Vault
- **URL**: `/api/notes/import`
- **Method**: `POST`
- **Description**: Import notes from an Obsidian vault
- **Request Body**: Multipart form with a `file` field containing the zip file
- **Response**: Import result
```json
{
"imported": 42
}
```
### Readlist
#### List Read Later Items
- **URL**: `/api/readlist`
- **Method**: `GET`
- **Description**: Get a list of all read later items
- **Query Parameters**:
- `status` - Filter by status (`read`, `unread`, `archived`, `unarchived`)
- **Response**: Array of ReadLaterItem objects
```json
[
{
"id": "item-id",
"url": "https://example.com/article",
"title": "Article Title",
"description": "Article description",
"createdAt": "2023-01-01T12:00:00Z",
"updatedAt": "2023-01-01T12:00:00Z",
"readAt": null,
"archivedAt": null
},
...
]
```
#### Save Article
- **URL**: `/api/readlist`
- **Method**: `POST`
- **Description**: Save a new article
- **Request Body**: ReadLaterItem object with URL
```json
{
"url": "https://example.com/article"
}
```
- **Response**: Created ReadLaterItem object
```json
{
"id": "item-id",
"url": "https://example.com/article",
"title": "Article Title",
"content": "Article content in HTML",
"description": "Article description",
"createdAt": "2023-01-01T12:00:00Z",
"updatedAt": "2023-01-01T12:00:00Z",
"readAt": null,
"archivedAt": null
}
```
#### Get Article
- **URL**: `/api/readlist/:id`
- **Method**: `GET`
- **Description**: Get a specific article by ID
- **URL Parameters**: `id` - ID of the article
- **Response**: ReadLaterItem object
```json
{
"id": "item-id",
"url": "https://example.com/article",
"title": "Article Title",
"content": "Article content in HTML",
"description": "Article description",
"createdAt": "2023-01-01T12:00:00Z",
"updatedAt": "2023-01-01T12:00:00Z",
"readAt": null,
"archivedAt": null
}
```
#### Mark as Read/Unread
- **URL**: `/api/readlist/:id/read` or `/api/readlist/:id/unread`
- **Method**: `PUT`
- **Description**: Mark an article as read or unread
- **URL Parameters**: `id` - ID of the article
- **Response**: Updated ReadLaterItem object
#### Archive/Unarchive
- **URL**: `/api/readlist/:id/archive` or `/api/readlist/:id/unarchive`
- **Method**: `PUT`
- **Description**: Archive or unarchive an article
- **URL Parameters**: `id` - ID of the article
- **Response**: Updated ReadLaterItem object
### Feeds
#### List Feeds
- **URL**: `/api/feeds`
- **Method**: `GET`
- **Description**: Get a list of all feeds
- **Response**: Array of Feed objects
```json
[
{
"id": "feed-id",
"title": "Feed Title",
"url": "https://example.com/feed.xml",
"description": "Feed description",
"siteUrl": "https://example.com",
"imageUrl": "https://example.com/logo.png",
"lastFetched": "2023-01-01T12:00:00Z",
"createdAt": "2023-01-01T12:00:00Z",
"updatedAt": "2023-01-01T12:00:00Z"
},
...
]
```
#### Subscribe to Feed
- **URL**: `/api/feeds`
- **Method**: `POST`
- **Description**: Subscribe to a new feed
- **Request Body**: Feed object with URL
```json
{
"url": "https://example.com/feed.xml"
}
```
- **Response**: Created Feed object
#### List Entries
- **URL**: `/api/feeds/entries` or `/api/feeds/:id/entries`
- **Method**: `GET`
- **Description**: Get a list of entries from all feeds or a specific feed
- **URL Parameters**: `id` (optional) - ID of the feed
- **Query Parameters**:
- `status` - Filter by status (`read`, `unread`)
- `limit` - Maximum number of entries to return
- `offset` - Offset for pagination
- **Response**: Array of Entry objects
```json
[
{
"id": "entry-id",
"feedId": "feed-id",
"title": "Entry Title",
"url": "https://example.com/article",
"content": "Entry content in HTML",
"summary": "Entry summary",
"author": "Author Name",
"published": "2023-01-01T12:00:00Z",
"updated": "2023-01-01T12:00:00Z",
"readAt": null,
"createdAt": "2023-01-01T12:00:00Z",
"updatedAt": "2023-01-01T12:00:00Z"
},
...
]
```
#### Refresh Feeds
- **URL**: `/api/feeds/refresh` or `/api/feeds/:id/refresh`
- **Method**: `POST`
- **Description**: Refresh all feeds or a specific feed
- **URL Parameters**: `id` (optional) - ID of the feed
- **Response**: Refresh result
```json
{
"newEntries": 5
}
```
## Error Handling
The API handles errors by returning appropriate HTTP status codes and error messages:
```json
{
"error": "Detailed error message"
}
```
Common error scenarios:
1. **Invalid Input**: Returns 400 Bad Request
2. **Resource Not Found**: Returns 404 Not Found
3. **Server Error**: Returns 500 Internal Server Error
## Rate Limiting
The API does not currently implement rate limiting as it is designed for local use.
## Versioning
The API does not currently implement versioning. Future versions may include a version prefix in the URL path (e.g., `/api/v1/notes`).