From 8b88a8e75bf0732c1cc757445a7444edb48c68d2 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Thu, 23 Jan 2020 19:39:59 -0500 Subject: Squashed commit of the following: commit f5b75f342bdc35b6c770358b2408a7ffc9ce80ad Merge: bd1fc2b 69389f6 Author: Dessalines Date: Thu Jan 23 19:17:42 2020 -0500 Done merging http-api and private_message commit bd1fc2b80b8c6a42f0df721d91863b8688b339ee Author: Dessalines Date: Thu Jan 23 16:46:07 2020 -0500 Remove danger from private-message.tsx commit 69389f61c9944319b5c71d7fb398294f1f8b8e7c Author: Dessalines Date: Thu Jan 23 11:21:21 2020 -0500 Fixing http curl POST docs. commit 7fdcae4f0739df79cbf8d7ea2138519d87f2aa32 Merge: dbe9ad0 752318f Author: Dessalines Date: Thu Jan 23 11:01:06 2020 -0500 Merge remote-tracking branch 'nutomic/http-api' into dessalines-http-api commit 752318fdf3cf95633744e89bbfe22a761fecc53d Author: Felix Date: Thu Jan 23 15:22:17 2020 +0100 api fixes commit 9ccff18f23509d309261670b57563b87e8f61f77 Author: Dessalines Date: Wed Jan 22 22:29:11 2020 -0500 Adding a toaster to replace alerts. Fixes #457 commit 5197407dd29a895fff37d4f0982e44d5e727d426 Merge: bacb9ac 58f673a Author: Dessalines Date: Wed Jan 22 21:20:38 2020 -0500 Merge branch 'private_messaging' into dev commit 58f673ab7856d2380cfaedbc46baf944fedfabb5 Author: Dessalines Date: Wed Jan 22 21:09:17 2020 -0500 Adding message to comment node actions. commit bacb9ac59ed3a6d8b4a80f37103ccf9c3ab751c9 Merge: 10c6505 7d3adda Author: Dessalines Date: Wed Jan 22 20:37:08 2020 -0500 Merge branch 'private_messaging' into dev commit 10c65059686ff74fc2ce412572e2d6fc3497c43a Author: Dessalines Date: Wed Jan 22 20:35:20 2020 -0500 Adding correct hello_name to mail. commit 7d3adda0cd4888e70b362cbad1b82f46d79c8d4c Author: Dessalines Date: Wed Jan 22 16:35:29 2020 -0500 Adding private messaging, and matrix user ids. - Fixes #244 commit dbe9ad0998b80d174130d82c11473555c7d6bc0e Author: Dessalines Date: Mon Jan 20 18:49:54 2020 -0500 Fixing last. commit 20c9c54806429395f8a4c1a4e7a6a0f677d4e6b8 Author: Dessalines Date: Sun Jan 19 13:31:37 2020 -0500 Updating API docs. commit dc84ccaac94b9887f8512e3c32aeea0df89520be Merge: 6c61dd2 3edd75e Author: Dessalines Date: Sun Jan 19 10:06:25 2020 -0500 Merge branch 'master' into dessalines-http-api commit 6c61dd266bb6e389312ec56e7fc50f4a6b71b374 Merge: c5eecd0 e518954 Author: Dessalines Date: Sun Jan 19 09:09:00 2020 -0500 Merge remote-tracking branch 'nutomic/websocket-generics' into dessalines-http-api commit e518954bcab2553906cec9f2bcfa6d1b5fdc2f38 Author: Felix Date: Sun Jan 19 14:25:50 2020 +0100 Use generics to reduce code duplication in websocket commit c5eecd055e79510421aebe26e5d4f173a5916a3e Author: Dessalines Date: Sun Jan 19 00:38:45 2020 -0500 Strongly typing WebsocketJsonResponse. Forgot comment-form.tsx commit 0c5eb471359929c532a4e6a63477a39ab6db67b6 Author: Dessalines Date: Sat Jan 18 23:54:10 2020 -0500 First pass at fixing UI to work with new websocketresponses. commit baf77bb6be88e796683bc21fd16a0359e68c7791 Author: Felix Date: Sat Jan 18 17:25:45 2020 +0100 simplify json serialization code commit 047ec97e1857888aeeac53629a76a4dc7e2f110b Author: Felix Date: Sat Jan 18 14:22:25 2020 +0100 rewrite api endpoint urls commit 2fb4900b0cf586674d6212e0aa2c1b852d104a1a Author: Felix Date: Thu Jan 16 17:04:37 2020 +0100 fix typo commit cba80815797b6578ab817b99fee35575cccef27d Author: Felix Date: Thu Jan 16 16:47:38 2020 +0100 fix formatting commit d7285d8c25c9a88c33519ec12f3c730d6b45fcf5 Author: Felix Date: Thu Jan 16 16:09:01 2020 +0100 small fix commit 415040a1e9b90fcb71872a41fbb6e7e7131d966d Author: Felix Date: Thu Jan 16 15:39:08 2020 +0100 working! commit 7a97c981a0b74cf6f66574690e58917a47508395 Author: Felix Date: Wed Jan 15 16:48:21 2020 +0100 try to simplify code with higher order functions commit c41082f98f459da2cc48dcfd7d9d5c2ac08865d0 Author: Felix Date: Wed Jan 15 16:37:25 2020 +0100 Implement HTTP API using generics (fixes #380) --- docs/src/SUMMARY.md | 2 +- docs/src/contributing_websocket_api.md | 1031 --------------------- docs/src/contributing_websocket_http_api.md | 1334 +++++++++++++++++++++++++++ 3 files changed, 1335 insertions(+), 1032 deletions(-) delete mode 100644 docs/src/contributing_websocket_api.md create mode 100644 docs/src/contributing_websocket_http_api.md (limited to 'docs') diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index d8916974..c2df6223 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -12,5 +12,5 @@ - [Contributing](contributing.md) - [Docker Development](contributing_docker_development.md) - [Local Development](contributing_local_development.md) - - [Websocket API](contributing_websocket_api.md) + - [Websocket/HTTP API](contributing_websocket_http_api.md) - [ActivityPub API Outline](contributing_apub_api_outline.md) diff --git a/docs/src/contributing_websocket_api.md b/docs/src/contributing_websocket_api.md deleted file mode 100644 index 16383d53..00000000 --- a/docs/src/contributing_websocket_api.md +++ /dev/null @@ -1,1031 +0,0 @@ -# Lemmy API -*Note: this may lag behind the actual API endpoints [here](../server/src/api).* - - - -- [Data types](#data-types) -- [Basic usage](#basic-usage) - * [WebSocket Endpoint](#websocket-endpoint) - * [Testing with Websocat](#testing-with-websocat) - * [Testing with the WebSocket JavaScript API](#testing-with-the-websocket-javascript-api) -- [Rate limits](#rate-limits) -- [Errors](#errors) -- [API documentation](#api-documentation) - * [Sort Types](#sort-types) - * [User / Authentication / Admin actions](#user--authentication--admin-actions) - + [Login](#login) - - [Request](#request) - - [Response](#response) - + [Register](#register) - - [Request](#request-1) - - [Response](#response-1) - + [Get User Details](#get-user-details) - - [Request](#request-2) - - [Response](#response-2) - + [Save User Settings](#save-user-settings) - - [Request](#request-3) - - [Response](#response-3) - + [Get Replies / Inbox](#get-replies--inbox) - - [Request](#request-4) - - [Response](#response-4) - + [Get User Mentions](#get-user-mentions) - - [Request](#request-5) - - [Response](#response-5) - + [Mark All As Read](#mark-all-as-read) - - [Request](#request-6) - - [Response](#response-6) - + [Delete Account](#delete-account) - - [Request](#request-7) - - [Response](#response-7) - + [Add admin](#add-admin) - - [Request](#request-8) - - [Response](#response-8) - + [Ban user](#ban-user) - - [Request](#request-9) - - [Response](#response-9) - * [Site](#site) - + [List Categories](#list-categories) - - [Request](#request-10) - - [Response](#response-10) - + [Search](#search) - - [Request](#request-11) - - [Response](#response-11) - + [Get Modlog](#get-modlog) - - [Request](#request-12) - - [Response](#response-12) - + [Create Site](#create-site) - - [Request](#request-13) - - [Response](#response-13) - + [Edit Site](#edit-site) - - [Request](#request-14) - - [Response](#response-14) - + [Get Site](#get-site) - - [Request](#request-15) - - [Response](#response-15) - + [Transfer Site](#transfer-site) - - [Request](#request-16) - - [Response](#response-16) - * [Community](#community) - + [Get Community](#get-community) - - [Request](#request-17) - - [Response](#response-17) - + [Create Community](#create-community) - - [Request](#request-18) - - [Response](#response-18) - + [List Communities](#list-communities) - - [Request](#request-19) - - [Response](#response-19) - + [Ban from Community](#ban-from-community) - - [Request](#request-20) - - [Response](#response-20) - + [Add Mod to Community](#add-mod-to-community) - - [Request](#request-21) - - [Response](#response-21) - + [Edit Community](#edit-community) - - [Request](#request-22) - - [Response](#response-22) - + [Follow Community](#follow-community) - - [Request](#request-23) - - [Response](#response-23) - + [Get Followed Communities](#get-followed-communities) - - [Request](#request-24) - - [Response](#response-24) - + [Transfer Community](#transfer-community) - - [Request](#request-25) - - [Response](#response-25) - * [Post](#post) - + [Create Post](#create-post) - - [Request](#request-26) - - [Response](#response-26) - + [Get Post](#get-post) - - [Request](#request-27) - - [Response](#response-27) - + [Get Posts](#get-posts) - - [Request](#request-28) - - [Response](#response-28) - + [Create Post Like](#create-post-like) - - [Request](#request-29) - - [Response](#response-29) - + [Edit Post](#edit-post) - - [Request](#request-30) - - [Response](#response-30) - + [Save Post](#save-post) - - [Request](#request-31) - - [Response](#response-31) - * [Comment](#comment) - + [Create Comment](#create-comment) - - [Request](#request-32) - - [Response](#response-32) - + [Edit Comment](#edit-comment) - - [Request](#request-33) - - [Response](#response-33) - + [Save Comment](#save-comment) - - [Request](#request-34) - - [Response](#response-34) - + [Create Comment Like](#create-comment-like) - - [Request](#request-35) - - [Response](#response-35) - * [RSS / Atom feeds](#rss--atom-feeds) - + [All](#all) - + [Community](#community-1) - + [User](#user) - - - -## Data types - -- `i16`, `i32` and `i64` are respectively [16-bit](https://en.wikipedia.org/wiki/16-bit), [32-bit](https://en.wikipedia.org/wiki/32-bit) and [64-bit](https://en.wikipedia.org/wiki/64-bit_computing) integers. -- Option<***SomeType***> designates an option which may be omitted in requests and not be present in responses. It will be of type ***SomeType***. -- Vec<***SomeType***> is a list which contains objects of type ***SomeType***. -- `chrono::NaiveDateTime` is a timestamp string in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. Timestamps will be UTC. -- Other data types are listed [here](../server/src/db). - -## Basic usage - -Request and response strings are in [JSON format](https://www.json.org). - -### WebSocket Endpoint - -Connect to ws://***host***/api/v1/ws to get started. - -If the ***`host`*** supports secure connections, you can use wss://***host***/api/v1/ws. - -### Testing with Websocat - -[Websocat link](https://github.com/vi/websocat) - -`websocat ws://127.0.0.1:8536/api/v1/ws -nt` - -A simple test command: -`{"op": "ListCategories"}` - -### Testing with the WebSocket JavaScript API - -[WebSocket JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) -```javascript -var ws = new WebSocket("ws://" + host + "/api/v1/ws"); -ws.onopen = function () { - console.log("Connection succeed!"); - ws.send(JSON.stringify({ - op: "ListCategories" - })); -}; -``` - -## Rate limits - -- 1 per hour for signups and community creation. -- 1 per 10 minutes for post creation. -- 30 actions per minute for post voting and comment creation. -- Everything else is not rate-limited. - -## Errors -```rust -{ - op: String, - message: String, -} -``` - -## API documentation - -### Sort Types - -These go wherever there is a `sort` field. The available sort types are: - -- `Hot` - the hottest posts/communities, depending on votes, views, comments and publish date -- `New` - the newest posts/communities -- `TopDay` - the most upvoted posts/communities of the current day. -- `TopWeek` - the most upvoted posts/communities of the current week. -- `TopMonth` - the most upvoted posts/communities of the current month. -- `TopYear` - the most upvoted posts/communities of the current year. -- `TopAll` - the most upvoted posts/communities on the current instance. - -### User / Authentication / Admin actions - -#### Login - -The `jwt` string should be stored and used anywhere `auth` is called for. - -##### Request -```rust -{ - op: "Login", - data: { - username_or_email: String, - password: String - } -} -``` -##### Response -```rust -{ - op: String, - jwt: String -} -``` - - -#### Register -Only the first user will be able to be the admin. - -##### Request -```rust -{ - op: "Register", - data: { - username: String, - email: Option, - password: String, - password_verify: String, - admin: bool - } -} -``` -##### Response -```rust -{ - op: String, - jwt: String -} -``` - -#### Get User Details -##### Request -```rust -{ - op: "GetUserDetails", - data: { - user_id: Option, - username: Option, - sort: String, - page: Option, - limit: Option, - community_id: Option, - saved_only: bool, - auth: Option, - } -} -``` -##### Response -```rust -{ - op: String, - user: UserView, - follows: Vec, - moderates: Vec, - comments: Vec, - posts: Vec, -} -``` -#### Save User Settings -##### Request -```rust -{ - op: "SaveUserSettings", - data: { - show_nsfw: bool, - theme: String, // Default 'darkly' - default_sort_type: i16, // The Sort types from above, zero indexed as a number - default_listing_type: i16, // Post listing types are `All, Subscribed, Community` - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - jwt: String -} -``` -#### Get Replies / Inbox -##### Request -```rust -{ - op: "GetReplies", - data: { - sort: String, - page: Option, - limit: Option, - unread_only: bool, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - replies: Vec, -} -``` - -#### Get User Mentions -##### Request -```rust -{ - op: "GetUserMentions", - data: { - sort: String, - page: Option, - limit: Option, - unread_only: bool, - auth: String, - } -} -``` -##### Response -```rust -{ - op: String, - mentions: Vec, -} -``` - -#### Mark All As Read - -Marks all user replies and mentions as read. - -##### Request -```rust -{ - op: "MarkAllAsRead", - data: { - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - replies: Vec, -} -``` - -#### Delete Account - -*Permananently deletes your posts and comments* - -##### Request -```rust -{ - op: "DeleteAccount", - data: { - password: String, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - jwt: String, -} -``` - -#### Add admin -##### Request -```rust -{ - op: "AddAdmin", - data: { - user_id: i32, - added: bool, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - admins: Vec, -} -``` - -#### Ban user -##### Request -```rust -{ - op: "BanUser", - data: { - user_id: i32, - ban: bool, - reason: Option, - expires: Option, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - user: UserView, - banned: bool, -} -``` - -### Site -#### List Categories -##### Request -```rust -{ - op: "ListCategories" -} -``` -##### Response -```rust -{ - op: String, - categories: Vec -} -``` - -#### Search -Search types are `Both, Comments, Posts`. - -##### Request -```rust -{ - op: "Search", - data: { - q: String, - type_: String, - community_id: Option, - sort: String, - page: Option, - limit: Option, - } -} -``` -##### Response -```rust -{ - op: String, - comments: Vec, - posts: Vec, -} -``` - -#### Get Modlog -##### Request -```rust -{ - op: "GetModlog", - data: { - mod_user_id: Option, - community_id: Option, - page: Option, - limit: Option, - } -} -``` -##### Response -```rust -{ - op: String, - removed_posts: Vec, - locked_posts: Vec, - removed_comments: Vec, - removed_communities: Vec, - banned_from_community: Vec, - banned: Vec, - added_to_community: Vec, - added: Vec, -} -``` - -#### Create Site -##### Request -```rust -{ - op: "CreateSite", - data: { - name: String, - description: Option, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - site: SiteView, -} -``` - -#### Edit Site -##### Request -```rust -{ - op: "EditSite", - data: { - name: String, - description: Option, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - site: SiteView, -} -``` - -#### Get Site -##### Request -```rust -{ - op: "GetSite" -} -``` -##### Response -```rust -{ - op: String, - site: Option, - admins: Vec, - banned: Vec, -} -``` - -#### Transfer Site -##### Request -```rust -{ - op: "TransferSite", - data: { - user_id: i32, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - site: Option, - admins: Vec, - banned: Vec, -} -``` - -### Community -#### Get Community -##### Request -```rust -{ - op: "GetCommunity", - data: { - id: Option, - name: Option, - auth: Option - } -} -``` -##### Response -```rust -{ - op: String, - community: CommunityView, - moderators: Vec, - admins: Vec, -} -``` - -#### Create Community -##### Request -```rust -{ - op: "CreateCommunity", - data: { - name: String, - title: String, - description: Option, - category_id: i32 , - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - community: CommunityView -} -``` - -#### List Communities -##### Request -```rust -{ - op: "ListCommunities", - data: { - sort: String, - page: Option, - limit: Option, - auth: Option - } -} -``` -##### Response -```rust -{ - op: String, - communities: Vec -} -``` - -#### Ban from Community -##### Request -```rust -{ - op: "BanFromCommunity", - data: { - community_id: i32, - user_id: i32, - ban: bool, - reason: Option, - expires: Option, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - user: UserView, - banned: bool, -} -``` - -#### Add Mod to Community -##### Request -```rust -{ - op: "AddModToCommunity", - data: { - community_id: i32, - user_id: i32, - added: bool, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - moderators: Vec, -} -``` - -#### Edit Community -Mods and admins can remove and lock a community, creators can delete it. - -##### Request -```rust -{ - op: "EditCommunity", - data: { - edit_id: i32, - name: String, - title: String, - description: Option, - category_id: i32, - removed: Option, - deleted: Option, - reason: Option, - expires: Option, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - community: CommunityView -} -``` - -#### Follow Community -##### Request -```rust -{ - op: "FollowCommunity", - data: { - community_id: i32, - follow: bool, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - community: CommunityView -} -``` - -#### Get Followed Communities -##### Request -```rust -{ - op: "GetFollowedCommunities", - data: { - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - communities: Vec -} -``` - -#### Transfer Community -##### Request -```rust -{ - op: "TransferCommunity", - data: { - community_id: i32, - user_id: i32, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - community: CommunityView, - moderators: Vec, - admins: Vec, -} -``` - -### Post -#### Create Post -##### Request -```rust -{ - op: "CreatePost", - data: { - name: String, - url: Option, - body: Option, - community_id: i32, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - post: PostView -} -``` - -#### Get Post -##### Request -```rust -{ - op: "GetPost", - data: { - id: i32, - auth: Option - } -} -``` -##### Response -```rust -{ - op: String, - post: PostView, - comments: Vec, - community: CommunityView, - moderators: Vec, - admins: Vec, -} -``` - -#### Get Posts -Post listing types are `All, Subscribed, Community` - -##### Request -```rust -{ - op: "GetPosts", - data: { - type_: String, - sort: String, - page: Option, - limit: Option, - community_id: Option, - auth: Option - } -} -``` -##### Response -```rust -{ - op: String, - posts: Vec, -} -``` - -#### Create Post Like -`score` can be 0, -1, or 1 - -##### Request -```rust -{ - op: "CreatePostLike", - data: { - post_id: i32, - score: i16, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - post: PostView -} -``` - -#### Edit Post -Mods and admins can remove and lock a post, creators can delete it. - -##### Request -```rust -{ - op: "EditPost", - data: { - edit_id: i32, - creator_id: i32, - community_id: i32, - name: String, - url: Option, - body: Option, - removed: Option, - deleted: Option, - locked: Option, - reason: Option, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - post: PostView -} -``` - -#### Save Post -##### Request -```rust -{ - op: "SavePost", - data: { - post_id: i32, - save: bool, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - post: PostView -} -``` - -### Comment -#### Create Comment -##### Request -```rust -{ - op: "CreateComment", - data: { - content: String, - parent_id: Option, - edit_id: Option, - post_id: i32, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - comment: CommentView -} -``` - -#### Edit Comment -Mods and admins can remove a comment, creators can delete it. - -##### Request -```rust -{ - op: "EditComment", - data: { - content: String, - parent_id: Option, - edit_id: i32, - creator_id: i32, - post_id: i32, - removed: Option, - deleted: Option, - reason: Option, - read: Option, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - comment: CommentView -} -``` - -#### Save Comment -##### Request -```rust -{ - op: "SaveComment", - data: { - comment_id: i32, - save: bool, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - comment: CommentView -} -``` - -#### Create Comment Like -`score` can be 0, -1, or 1 - -##### Request -```rust -{ - op: "CreateCommentLike", - data: { - comment_id: i32, - post_id: i32, - score: i16, - auth: String - } -} -``` -##### Response -```rust -{ - op: String, - comment: CommentView -} -``` - -### RSS / Atom feeds - -#### All - -`/feeds/all.xml?sort=Hot` - -#### Community - -`/feeds/c/community-name.xml?sort=Hot` - -#### User - -`/feeds/u/user-name.xml?sort=Hot` - diff --git a/docs/src/contributing_websocket_http_api.md b/docs/src/contributing_websocket_http_api.md new file mode 100644 index 00000000..9e87d4fa --- /dev/null +++ b/docs/src/contributing_websocket_http_api.md @@ -0,0 +1,1334 @@ +# Lemmy API +*Note: this may lag behind the actual API endpoints [here](../server/src/api).* + + + +- [Data types](#data-types) +- [Basic usage](#basic-usage) + * [WebSocket](#websocket) + + [Testing with Websocat](#testing-with-websocat) + + [Testing with the WebSocket JavaScript API](#testing-with-the-websocket-javascript-api) + * [HTTP](#http) + + [Testing with Curl](#testing-with-curl) + - [Get Example](#get-example) + - [Post Example](#post-example) +- [Rate limits](#rate-limits) +- [Errors](#errors) +- [API documentation](#api-documentation) + * [Sort Types](#sort-types) + * [Websocket vs HTTP](#websocket-vs-http) + * [User / Authentication / Admin actions](#user--authentication--admin-actions) + + [Login](#login) + - [Request](#request) + - [Response](#response) + - [HTTP](#http-1) + + [Register](#register) + - [Request](#request-1) + - [Response](#response-1) + - [HTTP](#http-2) + + [Get User Details](#get-user-details) + - [Request](#request-2) + - [Response](#response-2) + - [HTTP](#http-3) + + [Save User Settings](#save-user-settings) + - [Request](#request-3) + - [Response](#response-3) + - [HTTP](#http-4) + + [Get Replies / Inbox](#get-replies--inbox) + - [Request](#request-4) + - [Response](#response-4) + - [HTTP](#http-5) + + [Get User Mentions](#get-user-mentions) + - [Request](#request-5) + - [Response](#response-5) + - [HTTP](#http-6) + + [Edit User Mention](#edit-user-mention) + - [Request](#request-6) + - [Response](#response-6) + - [HTTP](#http-7) + + [Mark All As Read](#mark-all-as-read) + - [Request](#request-7) + - [Response](#response-7) + - [HTTP](#http-8) + + [Delete Account](#delete-account) + - [Request](#request-8) + - [Response](#response-8) + - [HTTP](#http-9) + + [Add admin](#add-admin) + - [Request](#request-9) + - [Response](#response-9) + - [HTTP](#http-10) + + [Ban user](#ban-user) + - [Request](#request-10) + - [Response](#response-10) + - [HTTP](#http-11) + * [Site](#site) + + [List Categories](#list-categories) + - [Request](#request-11) + - [Response](#response-11) + - [HTTP](#http-12) + + [Search](#search) + - [Request](#request-12) + - [Response](#response-12) + - [HTTP](#http-13) + + [Get Modlog](#get-modlog) + - [Request](#request-13) + - [Response](#response-13) + - [HTTP](#http-14) + + [Create Site](#create-site) + - [Request](#request-14) + - [Response](#response-14) + - [HTTP](#http-15) + + [Edit Site](#edit-site) + - [Request](#request-15) + - [Response](#response-15) + - [HTTP](#http-16) + + [Get Site](#get-site) + - [Request](#request-16) + - [Response](#response-16) + - [HTTP](#http-17) + + [Transfer Site](#transfer-site) + - [Request](#request-17) + - [Response](#response-17) + - [HTTP](#http-18) + * [Community](#community) + + [Get Community](#get-community) + - [Request](#request-18) + - [Response](#response-18) + - [HTTP](#http-19) + + [Create Community](#create-community) + - [Request](#request-19) + - [Response](#response-19) + - [HTTP](#http-20) + + [List Communities](#list-communities) + - [Request](#request-20) + - [Response](#response-20) + - [HTTP](#http-21) + + [Ban from Community](#ban-from-community) + - [Request](#request-21) + - [Response](#response-21) + - [HTTP](#http-22) + + [Add Mod to Community](#add-mod-to-community) + - [Request](#request-22) + - [Response](#response-22) + - [HTTP](#http-23) + + [Edit Community](#edit-community) + - [Request](#request-23) + - [Response](#response-23) + - [HTTP](#http-24) + + [Follow Community](#follow-community) + - [Request](#request-24) + - [Response](#response-24) + - [HTTP](#http-25) + + [Get Followed Communities](#get-followed-communities) + - [Request](#request-25) + - [Response](#response-25) + - [HTTP](#http-26) + + [Transfer Community](#transfer-community) + - [Request](#request-26) + - [Response](#response-26) + - [HTTP](#http-27) + * [Post](#post) + + [Create Post](#create-post) + - [Request](#request-27) + - [Response](#response-27) + - [HTTP](#http-28) + + [Get Post](#get-post) + - [Request](#request-28) + - [Response](#response-28) + - [HTTP](#http-29) + + [Get Posts](#get-posts) + - [Request](#request-29) + - [Response](#response-29) + - [HTTP](#http-30) + + [Create Post Like](#create-post-like) + - [Request](#request-30) + - [Response](#response-30) + - [HTTP](#http-31) + + [Edit Post](#edit-post) + - [Request](#request-31) + - [Response](#response-31) + - [HTTP](#http-32) + + [Save Post](#save-post) + - [Request](#request-32) + - [Response](#response-32) + - [HTTP](#http-33) + * [Comment](#comment) + + [Create Comment](#create-comment) + - [Request](#request-33) + - [Response](#response-33) + - [HTTP](#http-34) + + [Edit Comment](#edit-comment) + - [Request](#request-34) + - [Response](#response-34) + - [HTTP](#http-35) + + [Save Comment](#save-comment) + - [Request](#request-35) + - [Response](#response-35) + - [HTTP](#http-36) + + [Create Comment Like](#create-comment-like) + - [Request](#request-36) + - [Response](#response-36) + - [HTTP](#http-37) + * [RSS / Atom feeds](#rss--atom-feeds) + + [All](#all) + + [Community](#community-1) + + [User](#user) + + + +## Data types + +- `i16`, `i32` and `i64` are respectively [16-bit](https://en.wikipedia.org/wiki/16-bit), [32-bit](https://en.wikipedia.org/wiki/32-bit) and [64-bit](https://en.wikipedia.org/wiki/64-bit_computing) integers. +- Option<***SomeType***> designates an option which may be omitted in requests and not be present in responses. It will be of type ***SomeType***. +- Vec<***SomeType***> is a list which contains objects of type ***SomeType***. +- `chrono::NaiveDateTime` is a timestamp string in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. Timestamps will be UTC. +- Other data types are listed [here](../server/src/db). + +## Basic usage + +Request and response strings are in [JSON format](https://www.json.org). + +### WebSocket + +Connect to ws://***host***/api/v1/ws to get started. + +If the ***`host`*** supports secure connections, you can use wss://***host***/api/v1/ws. + +#### Testing with Websocat + +[Websocat link](https://github.com/vi/websocat) + +`websocat ws://127.0.0.1:8536/api/v1/ws -nt` + +A simple test command: +`{"op": "ListCategories"}` + +#### Testing with the WebSocket JavaScript API + +[WebSocket JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) +```javascript +var ws = new WebSocket("ws://" + host + "/api/v1/ws"); +ws.onopen = function () { + console.log("Connection succeed!"); + ws.send(JSON.stringify({ + op: "ListCategories" + })); +}; +``` +### HTTP + +Endpoints are at http://***host***/api/v1/***endpoint***. They'll be listed below for each action. + +#### Testing with Curl + +##### Get Example + +``` +curl /community/list?sort=Hot +``` + +##### Post Example + +``` +curl -i -H \ +"Content-Type: application/json" \ +-X POST \ +-d '{ + "comment_id": X, + "post_id": X, + "score": X, + "auth": "..." +}' \ +/comment/like +``` + +## Rate limits + +- 1 per hour for signups and community creation. +- 1 per 10 minutes for post creation. +- 30 actions per minute for post voting and comment creation. +- Everything else is not rate-limited. + +## Errors +```rust +{ + op: String, + message: String, +} +``` + +## API documentation + +### Sort Types + +These go wherever there is a `sort` field. The available sort types are: + +- `Hot` - the hottest posts/communities, depending on votes, views, comments and publish date +- `New` - the newest posts/communities +- `TopDay` - the most upvoted posts/communities of the current day. +- `TopWeek` - the most upvoted posts/communities of the current week. +- `TopMonth` - the most upvoted posts/communities of the current month. +- `TopYear` - the most upvoted posts/communities of the current year. +- `TopAll` - the most upvoted posts/communities on the current instance. + +### Websocket vs HTTP + +- Below are the websocket JSON requests / responses. For HTTP, ignore all fields except those inside `data`. +- For example, an http login will be a `POST` `{username_or_email: X, password: X}` + +### User / Authentication / Admin actions + +#### Login + +The `jwt` string should be stored and used anywhere `auth` is called for. + +##### Request +```rust +{ + op: "Login", + data: { + username_or_email: String, + password: String + } +} +``` +##### Response +```rust +{ + op: "Login", + data: { + jwt: String, + } +} +``` + +##### HTTP + +`POST /user/login` + +#### Register + +Only the first user will be able to be the admin. + +##### Request +```rust +{ + op: "Register", + data: { + username: String, + email: Option, + password: String, + password_verify: String, + admin: bool + } +} +``` +##### Response +```rust +{ + op: "Register", + data: { + jwt: String, + } +} +``` + +##### HTTP + +`POST /user/register` + +#### Get User Details +##### Request +```rust +{ + op: "GetUserDetails", + data: { + user_id: Option, + username: Option, + sort: String, + page: Option, + limit: Option, + community_id: Option, + saved_only: bool, + auth: Option, + } +} +``` +##### Response +```rust +{ + op: "GetUserDetails", + data: { + user: UserView, + follows: Vec, + moderates: Vec, + comments: Vec, + posts: Vec, + } +} +``` +##### HTTP + +`GET /user` + +#### Save User Settings +##### Request +```rust +{ + op: "SaveUserSettings", + data: { + show_nsfw: bool, + theme: String, // Default 'darkly' + default_sort_type: i16, // The Sort types from above, zero indexed as a number + default_listing_type: i16, // Post listing types are `All, Subscribed, Community` + auth: String + } +} +``` +##### Response +```rust +{ + op: "SaveUserSettings", + data: { + jwt: String + } +} +``` +##### HTTP + +`PUT /save_user_settings` + +#### Get Replies / Inbox +##### Request +```rust +{ + op: "GetReplies", + data: { + sort: String, + page: Option, + limit: Option, + unread_only: bool, + auth: String + } +} +``` +##### Response +```rust +{ + op: "GetReplies", + data: { + replies: Vec, + } +} +``` +##### HTTP + +`GET /user/replies` + + +#### Get User Mentions +##### Request +```rust +{ + op: "GetUserMentions", + data: { + sort: String, + page: Option, + limit: Option, + unread_only: bool, + auth: String, + } +} +``` +##### Response +```rust +{ + op: "GetUserMentions", + data: { + mentions: Vec, + } +} +``` + +##### HTTP + +`GET /user/mentions` + +#### Edit User Mention +##### Request +```rust +{ + op: "EditUserMention", + data: { + user_mention_id: i32, + read: Option, + auth: String, + } +} +``` +##### Response +```rust +{ + op: "EditUserMention", + data: { + mention: UserMentionView, + } +} +``` +##### HTTP + +`PUT /user/mention` + +#### Mark All As Read + +Marks all user replies and mentions as read. + +##### Request +```rust +{ + op: "MarkAllAsRead", + data: { + auth: String + } +} +``` +##### Response +```rust +{ + op: "MarkAllAsRead", + data: { + replies: Vec, + } +} +``` + +##### HTTP + +`POST /user/mark_all_as_read` + +#### Delete Account + +*Permananently deletes your posts and comments* + +##### Request +```rust +{ + op: "DeleteAccount", + data: { + password: String, + auth: String + } +} +``` +##### Response +```rust +{ + op: "DeleteAccount", + data: { + jwt: String, + } +} +``` + +##### HTTP + +`POST /user/delete_account` + +#### Add admin +##### Request +```rust +{ + op: "AddAdmin", + data: { + user_id: i32, + added: bool, + auth: String + } +} +``` +##### Response +```rust +{ + op: "AddAdmin", + data: { + admins: Vec, + } +} +``` +##### HTTP + +`POST /admin/add` + +#### Ban user +##### Request +```rust +{ + op: "BanUser", + data: { + user_id: i32, + ban: bool, + reason: Option, + expires: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: "BanUser", + data: { + user: UserView, + banned: bool, + } +} +``` +##### HTTP + +`POST /user/ban` + +### Site +#### List Categories +##### Request +```rust +{ + op: "ListCategories" +} +``` +##### Response +```rust +{ + op: "ListCategories", + data: { + categories: Vec + } +} +``` +##### HTTP + +`GET /categories` + +#### Search + +Search types are `All, Comments, Posts, Communities, Users, Url` + +##### Request +```rust +{ + op: "Search", + data: { + q: String, + type_: String, + community_id: Option, + sort: String, + page: Option, + limit: Option, + auth?: Option, + } +} +``` +##### Response +```rust +{ + op: "Search", + data: { + type_: String, + comments: Vec, + posts: Vec, + communities: Vec, + users: Vec, + } +} +``` +##### HTTP + +`POST /search` + +#### Get Modlog +##### Request +```rust +{ + op: "GetModlog", + data: { + mod_user_id: Option, + community_id: Option, + page: Option, + limit: Option, + } +} +``` +##### Response +```rust +{ + op: "GetModlog", + data: { + removed_posts: Vec, + locked_posts: Vec, + removed_comments: Vec, + removed_communities: Vec, + banned_from_community: Vec, + banned: Vec, + added_to_community: Vec, + added: Vec, + } +} +``` + +##### HTTP + +`GET /modlog` + +#### Create Site +##### Request +```rust +{ + op: "CreateSite", + data: { + name: String, + description: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: "CreateSite", + data: { + site: SiteView, + } +} +``` + +##### HTTP + +`POST /site` + +#### Edit Site +##### Request +```rust +{ + op: "EditSite", + data: { + name: String, + description: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: "EditSite", + data: { + site: SiteView, + } +} +``` +##### HTTP + +`PUT /site` + +#### Get Site +##### Request +```rust +{ + op: "GetSite" +} +``` +##### Response +```rust +{ + op: "GetSite", + data: { + site: Option, + admins: Vec, + banned: Vec, + } +} +``` +##### HTTP + +`GET /site` + +#### Transfer Site +##### Request +```rust +{ + op: "TransferSite", + data: { + user_id: i32, + auth: String + } +} +``` +##### Response +```rust +{ + op: "TransferSite", + data: { + site: Option, + admins: Vec, + banned: Vec, + } +} +``` +##### HTTP + +`POST /site/transfer` + +### Community +#### Get Community +##### Request +```rust +{ + op: "GetCommunity", + data: { + id: Option, + name: Option, + auth: Option + } +} +``` +##### Response +```rust +{ + op: "GetCommunity", + data: { + community: CommunityView, + moderators: Vec, + admins: Vec, + } +} +``` +##### HTTP + +`GET /community` + +#### Create Community +##### Request +```rust +{ + op: "CreateCommunity", + data: { + name: String, + title: String, + description: Option, + category_id: i32 , + auth: String + } +} +``` +##### Response +```rust +{ + op: "CreateCommunity", + data: { + community: CommunityView + } +} +``` +##### HTTP + +`POST /community` + +#### List Communities +##### Request +```rust +{ + op: "ListCommunities", + data: { + sort: String, + page: Option, + limit: Option, + auth: Option + } +} +``` +##### Response +```rust +{ + op: "ListCommunities", + data: { + communities: Vec + } +} +``` +##### HTTP + +`GET /community/list` + +#### Ban from Community +##### Request +```rust +{ + op: "BanFromCommunity", + data: { + community_id: i32, + user_id: i32, + ban: bool, + reason: Option, + expires: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: "BanFromCommunity", + data: { + user: UserView, + banned: bool, + } +} +``` +##### HTTP + +`POST /community/ban_user` + +#### Add Mod to Community +##### Request +```rust +{ + op: "AddModToCommunity", + data: { + community_id: i32, + user_id: i32, + added: bool, + auth: String + } +} +``` +##### Response +```rust +{ + op: "AddModToCommunity", + data: { + moderators: Vec, + } +} +``` +##### HTTP + +`POST /community/mod` + +#### Edit Community +Mods and admins can remove and lock a community, creators can delete it. + +##### Request +```rust +{ + op: "EditCommunity", + data: { + edit_id: i32, + name: String, + title: String, + description: Option, + category_id: i32, + removed: Option, + deleted: Option, + reason: Option, + expires: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: "EditCommunity", + data: { + community: CommunityView + } +} +``` +##### HTTP + +`PUT /community` + +#### Follow Community +##### Request +```rust +{ + op: "FollowCommunity", + data: { + community_id: i32, + follow: bool, + auth: String + } +} +``` +##### Response +```rust +{ + op: "FollowCommunity", + data: { + community: CommunityView + } +} +``` +##### HTTP + +`POST /community/follow` + +#### Get Followed Communities +##### Request +```rust +{ + op: "GetFollowedCommunities", + data: { + auth: String + } +} +``` +##### Response +```rust +{ + op: "GetFollowedCommunities", + data: { + communities: Vec + } +} +``` +##### HTTP + +`GET /user/followed_communities` + +#### Transfer Community +##### Request +```rust +{ + op: "TransferCommunity", + data: { + community_id: i32, + user_id: i32, + auth: String + } +} +``` +##### Response +```rust +{ + op: "TransferCommunity", + data: { + community: CommunityView, + moderators: Vec, + admins: Vec, + } +} +``` +##### HTTP + +`POST /community/transfer` + +### Post +#### Create Post +##### Request +```rust +{ + op: "CreatePost", + data: { + name: String, + url: Option, + body: Option, + community_id: i32, + auth: String + } +} +``` +##### Response +```rust +{ + op: "CreatePost", + data: { + post: PostView + } +} +``` +##### HTTP + +`POST /post` + +#### Get Post +##### Request +```rust +{ + op: "GetPost", + data: { + id: i32, + auth: Option + } +} +``` +##### Response +```rust +{ + op: "GetPost", + data: { + post: PostView, + comments: Vec, + community: CommunityView, + moderators: Vec, + admins: Vec, + } +} +``` +##### HTTP + +`GET /post` + +#### Get Posts + +Post listing types are `All, Subscribed, Community` + +##### Request +```rust +{ + op: "GetPosts", + data: { + type_: String, + sort: String, + page: Option, + limit: Option, + community_id: Option, + auth: Option + } +} +``` +##### Response +```rust +{ + op: "GetPosts", + data: { + posts: Vec, + } +} +``` +##### HTTP + +`GET /post/list` + +#### Create Post Like + +`score` can be 0, -1, or 1 + +##### Request +```rust +{ + op: "CreatePostLike", + data: { + post_id: i32, + score: i16, + auth: String + } +} +``` +##### Response +```rust +{ + op: "CreatePostLike", + data: { + post: PostView + } +} +``` +##### HTTP + +`POST /post/like` + +#### Edit Post + +Mods and admins can remove and lock a post, creators can delete it. + +##### Request +```rust +{ + op: "EditPost", + data: { + edit_id: i32, + creator_id: i32, + community_id: i32, + name: String, + url: Option, + body: Option, + removed: Option, + deleted: Option, + locked: Option, + reason: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: "EditPost", + data: { + post: PostView + } +} +``` + +##### HTTP + +`PUT /post` + +#### Save Post +##### Request +```rust +{ + op: "SavePost", + data: { + post_id: i32, + save: bool, + auth: String + } +} +``` +##### Response +```rust +{ + op: "SavePost", + data: { + post: PostView + } +} +``` +##### HTTP + +`POST /post/save` + +### Comment +#### Create Comment +##### Request +```rust +{ + op: "CreateComment", + data: { + content: String, + parent_id: Option, + edit_id: Option, + post_id: i32, + auth: String + } +} +``` +##### Response +```rust +{ + op: "CreateComment", + data: { + comment: CommentView + } +} +``` + +##### HTTP + +`POST /comment` + +#### Edit Comment + +Mods and admins can remove a comment, creators can delete it. + +##### Request +```rust +{ + op: "EditComment", + data: { + content: String, + parent_id: Option, + edit_id: i32, + creator_id: i32, + post_id: i32, + removed: Option, + deleted: Option, + reason: Option, + read: Option, + auth: String + } +} +``` +##### Response +```rust +{ + op: "EditComment", + data: { + comment: CommentView + } +} +``` +##### HTTP + +`PUT /comment` + +#### Save Comment +##### Request +```rust +{ + op: "SaveComment", + data: { + comment_id: i32, + save: bool, + auth: String + } +} +``` +##### Response +```rust +{ + op: "SaveComment", + data: { + comment: CommentView + } +} +``` +##### HTTP + +`POST /comment/save` + +#### Create Comment Like + +`score` can be 0, -1, or 1 + +##### Request +```rust +{ + op: "CreateCommentLike", + data: { + comment_id: i32, + post_id: i32, + score: i16, + auth: String + } +} +``` +##### Response +```rust +{ + op: "CreateCommentLike", + data: { + comment: CommentView + } +} +``` +##### HTTP + +`POST /comment/like` + +### RSS / Atom feeds + +#### All + +`/feeds/all.xml?sort=Hot` + +#### Community + +`/feeds/c/community-name.xml?sort=Hot` + +#### User + +`/feeds/u/user-name.xml?sort=Hot` + -- cgit v1.2.3