├── 01-blogging-website ├── API.md └── README.md ├── 02-shopping-site ├── API.md ├── README.md └── payment_flow.png ├── 03-social-media-site ├── API.md ├── README.md ├── m-n-relationship.png └── post_relationship.png └── README.md /01-blogging-website/API.md: -------------------------------------------------------------------------------- 1 | # API 2 | 3 | Base URL: `https://api.blogging.site/v1/` 4 | 5 | ## Authentication 6 | 7 | ``` 8 | Authorization: Token 9 | ``` 10 | 11 | ## Generic Responses 12 | 13 | ### Success 14 | ```json 15 | { 16 | "status": "success", 17 | "code": 200, 18 | "message": "Success message", 19 | "data": {}, 20 | "meta": { 21 | "page": 1, 22 | "limit": 10, 23 | "total_pages": 100 24 | } 25 | } 26 | ``` 27 | 28 | ### Error 29 | 30 | ```json 31 | { 32 | "status": "error", 33 | "code": 400, 34 | "message": "Bad Request", 35 | "data": null, 36 | "meta": {} 37 | } 38 | ``` 39 | 40 | 41 | ## Endpoints 42 | 43 | > HTTP Methods -> verb 44 | > Entities/Resources -> noun 45 | > 46 | > GET fetch/find/read 47 | > POST create/submit 48 | > PUT create (with id)/replace/overwrite 49 | > PATCH update/modify existing 50 | > DELETE delete 51 | > OPTIONS find possible methods 52 | > HEAD 53 | 54 | ### Users 55 | 56 | #### `POST /users` - Signup/Register user 57 | 58 | **Responses** 59 | - 201 - Created 60 | - 409 - Conflict (User already exists) 61 | - 400 - Bad Request (Validation error) 62 | 63 | 64 | #### `POST /users/login` - Login user 65 | 66 | **Request Body** 67 | ``` 68 | { 69 | "email": "arnav09@mail.com" 70 | "password": "pass09" 71 | } 72 | ``` 73 | 74 | **Responses** 75 | - 200 - OK 76 | ``` 77 | { 78 | "status": "success", 79 | "code": 200, 80 | "message": "Success message", 81 | "data": { 82 | "user": { 83 | "username": "arnav09", 84 | "email": "arnav09@mail.com", 85 | "token": "" 86 | } 87 | }, 88 | "meta": { 89 | "page": 1, 90 | "limit": 10, 91 | "total_pages": 100 92 | } 93 | } 94 | ``` 95 | - 404 - Not Found (User not found) 96 | - 401 - Unauthorized (Invalid credentials) 97 | 98 | #### `PATCH /users/me` 🔐 - Update user profile 99 | 100 | **Responses** 101 | - 202 - Accepted 102 | - 401 - Unauthorized (Invalid credentials) 103 | - 400 - Bad Request (Validation error) 104 | 105 | #### `GET /users/{username}` 🔐 - Fetch user profile 106 | 107 | **Responses** 108 | - 200 - OK 109 | - 401 - Unauthorized (Invalid credentials) 110 | - 404 - Not Found (User not found) 111 | 112 | #### `PUT /users/{username}/follow` 🔐 - Follow user 113 | 114 | **Responses** 115 | - 202 - Accepted 116 | - 401 - Unauthorized (Invalid credentials) 117 | - 404 - Not Found (User not found) 118 | 119 | #### `DELETE /users/{username}/follow` 🔐 - Un-follow user 120 | 121 | **Responses** 122 | - 202 - Accepted 123 | - 401 - Unauthorized (Invalid credentials) 124 | - 404 - Not Found (User not found) 125 | 126 | #### `GET /users/{username}/followers` - Fetch followers of user 127 | 128 | **Responses** 129 | - 200 - OK 130 | - 401 - Unauthorized (Invalid credentials) 131 | - 404 - Not Found (User not found) 132 | 133 | ### Articles 134 | 135 | #### `GET /articles` 📄 - Fetch all articles 136 | - Query Params 137 | - `tags=tag1,tag2` - Filter by tags 138 | - `author=username` - Filter by author 139 | - `sort=new` - Sort by created_at desc 140 | - `sort=popular` - Sort by likes desc 141 | - `limit=10&page=1` - Pagination 142 | 143 | #### `GET /articles?only_following=true` 🔐 - Fetch articles written by users whom the logged in user follows 144 | 145 | #### `GET /articles/{slug}` - Fetch single article 146 | 147 | #### `POST /articles` 🔐 - Create new article 148 | 149 | **Responses** 150 | - 201 - Created 151 | - 401 - Unauthorized (Invalid credentials) 152 | - 400 - Bad Request (Validation error) 153 | 154 | #### `PATCH /articles/{slug}` 🔐 - Update article 155 | 156 | **Responses** 157 | 158 | - 202 - Accepted 159 | - 404 - Not Found (Article not found) 160 | - 401 - Unauthorized (Invalid credentials) 161 | - 403 - Forbidden (User is not the author) 162 | - 400 - Bad Request (Validation error) 163 | 164 | #### `DELETE /articles/{slug}` 🔐 - Delete article 165 | 166 | **Responses** 167 | 168 | - 202 - Accepted 169 | - 404 - Not Found (Article not found) 170 | - 401 - Unauthorized (Invalid credentials) 171 | - 403 - Forbidden (User is not the author) 172 | - 400 - Bad Request (Validation error) 173 | 174 | #### `PUT /articles/{slug}/like` 🔐 - Like article 175 | 176 | #### `DELETE /articles/{slug}/like` 🔐 - Unlike article 177 | 178 | 179 | ### Comments 180 | 181 | #### `GET /articles/{slug}/comments` - Fetch all comments of an article 182 | 183 | #### `POST /articles/{slug}/comments` 🔐 - Create new comment 184 | 185 | #### `DELETE /articles/{slug}/comments/{id}` 🔐 - Delete comment 186 | 187 | 188 | ## Notes 189 | 190 | ### POST vs PUT 191 | 192 | - `POST /articles` - creates an article 193 | - server decides the id of this new article 194 | - `PUT /articles/{id}` - creates an article with a specific id 195 | - client decides the id of this new article 196 | - cannot use with eg: auto-incrementing ids 197 | - can be used if using uuids/guids -------------------------------------------------------------------------------- /01-blogging-website/README.md: -------------------------------------------------------------------------------- 1 | # Blogging Website 2 | 3 | # Entities 4 | 5 | ## User 6 | - id 7 | - created_at 8 | - updated_at 9 | - username 10 | - email 11 | - password 12 | - image 13 | - bio 14 | 15 | ## Article 16 | - id 17 | - created_at 18 | - updated_at // deleted_at or active (for soft delete) 19 | - slug 20 | - title 21 | - subtitle 22 | - body 23 | - author_id // reference to user 24 | - likes 25 | 26 | ## Comment 27 | - id 28 | - created_at 29 | - updated_at 30 | - body 31 | - author_id // reference to user 32 | - article_id // reference to article 33 | 34 | ## Tags 35 | - id 36 | - created_at 37 | - updated_at 38 | - name 39 | 40 | ### Mapping Entities 41 | 42 | #### Article - Tag (Tags) 43 | - article_id 44 | - tag_id 45 | 46 | #### User - Article (Likes / Favourites) 47 | - user_id 48 | - article_id 49 | 50 | #### User - User (Follows) 51 | - follower_id 52 | - followee_id 53 | 54 | # Functional Requirements 55 | 56 | ## Users 57 | 58 | - User can register 59 | - User who has already registered, can login 60 | - Users can update their profile 61 | - Users can see other user's profile 62 | - Users can (un)follow other users 63 | 64 | ## Articles 65 | 66 | - Guests/Users can fetch all articles 67 | - Filter by tags 68 | - Filter by authors 69 | - Sort by created_at 70 | - Sort by likes 71 | - Guests/Users can fetch a single article 72 | - Users can fetch articles written users whom they follow (Your Feed) 73 | - Users can create new articles 74 | - Required tags will be created and associated to article 75 | - Users can update their own articles 76 | - Users can delete their own articles 77 | - Users can (un)favourite an article 78 | 79 | ## Comments 80 | 81 | - Guests/Users can fetch all comments for an article 82 | - Users can comment on articles 83 | - Users can delete their own comments -------------------------------------------------------------------------------- /02-shopping-site/API.md: -------------------------------------------------------------------------------- 1 | # API - Shopping Site 2 | 3 | Base URL: `https://api.shopping.site/v1/` 4 | 5 | ## Generic Responses 6 | 7 | ### Success 8 | 9 | ```json 10 | { 11 | "status": "success", 12 | "code": 200, 13 | "message": "Success message", 14 | "data": {}, 15 | "meta": { 16 | "page": 1, 17 | "limit": 10, 18 | "total": 100 19 | } 20 | } 21 | ``` 22 | 23 | ### Errors 24 | 25 | ```json 26 | { 27 | "status": "error", 28 | "code": 400, 29 | "message": "Bad Request", 30 | "data": {}, 31 | "meta": {} 32 | } 33 | ``` 34 | 35 | ## Authentication 36 | 37 | **Header** 38 | 39 | ``` 40 | Authorization: Token 41 | ``` 42 | 43 | ## Endpoints 44 | 45 | ### User 46 | 47 | #### `POST /users` - signup / register a new user 48 | 49 | #### `POST /users/login` - login a user 50 | 51 | #### `POST /users/logout` 🔐 - logout a user 52 | 53 | #### `GET /users/{user_id/user_email}` 🔐 - get user details 54 | 55 | #### `PATCH /users/me` 🔐 - update user details 56 | 57 | 58 | ### Address 59 | 60 | #### `GET /users/me/addresses` 🔐 - list all addresses 61 | 62 | #### `POST /users/me/addresses` 🔐 - add a new address 63 | 64 | #### `PATCH /users/me/addresses/{address_id}` 🔐 - update an address 65 | 66 | #### `DELETE /users/me/addresses/{address_id}` 🔐 - delete an address 67 | 68 | ### Product 69 | 70 | #### `POST /products` 🔐👮‍♀️ - add a new product 71 | 72 | #### `PATCH /products/{product_id}` 🔐👮‍♀️ - update a product 73 | 74 | #### `GET /products` - list all products 75 | - `?vendor_id=123` - filter by vendor 76 | - `?search=keyword` - search by name 77 | - `?min_price=100&max_price=200` - filter by price 78 | 79 | #### `GET /products/{group_id/product_id}` - get details of a product 80 | 81 | Variant A: Only search by `group_id` 82 | - if only one product of groupid exists 83 | - `[{title, price, ...}]` 84 | - if multiple products of groupid exists 85 | - `[{title, price, ...}, {title, price, ...}, {title, price, ...}]` 86 | 87 | Variant B: Only search by `group_id` 88 | - if only one product of groupid exists 89 | - `{title, price, ...}` 90 | - if multiple products of groupid exists 91 | - `{title, price, ..., variants: [{color}, {color}, {color}]}` 92 | 93 | Variant C: Only search by `product_id` 94 | - in all cases - similar response (`grouped_products` empty for single product) 95 | ``` 96 | { 97 | title, 98 | price, 99 | color 100 | ... 101 | grouped_products: [ 102 | {title, price, color, ...}, 103 | {title, price, color, ...}, 104 | ] 105 | } 106 | ``` 107 | 108 | ### Cart 109 | 110 | #### `GET /cart` 🔐 - list all products in cart 111 | 112 | #### `PUT /cart/{product_id}` 🔐 - add product to cart 113 | - `?buy_now=true` - will create temp cart to turn into order immediately 114 | - body : `{quantity}` 115 | 116 | #### `PATCH /cart/{product_id}` 🔐 - update product in cart 117 | - body : `{quantity_incr: }` 118 | - body : `{quantity_decr: }` 119 | - > NOTE: We can use `PUT` with absolute quantity and remove this endpoint 120 | 121 | #### `DELETE /cart/{product_id}` 🔐 - remove product from cart 122 | 123 | #### `DELETE /cart` 🔐 - clear all products from cart 124 | 125 | ### Vendor Orders 126 | 127 | #### `GET /vendor_orders` 🔐 - list all orders for vendor 128 | 129 | #### `GET /vendor_orders/{order_id}` 🔐 - get details of an order 130 | 131 | ### Order 132 | 133 | #### `POST /orders` 🔐 - create a new order with existing cart 134 | - body : `{billing_address_id, shipping_address_id}` 135 | - body + `{cart_id}` if multiple carts/user is allowed 136 | 137 | #### `GET /orders` 🔐 - list all orders 138 | - `?sort=created_desc` - filter by created date 139 | 140 | #### `GET /orders/{order_id}` 🔐 - get details of an order 141 | 142 | #### `PATCH /orders/{order_id}` 🔐 - cancel an order 143 | - body : `{status: "cancelled"}` 144 | 145 | 146 | ### Payment 147 | 148 | #### `GET /orders/{order_id}/payments/{payment_id}` 🔐 - get payment status 149 | 150 | #### `PATCH /orders/{order_id}/payments/{payment_id}` 🔐 - update payment status 151 | - body : `{pg_txn_id: "....", status: "success"}` 152 | 153 | 154 | 155 | ## Notes 156 | 157 | ## REST API Principles 158 | 159 | - "users", "products" 160 | - entities / resources 161 | - used as "nouns" 162 | - part of the URL path 163 | 164 | - "create", "update", "delete" 165 | - actions 166 | - used as "verbs" 167 | - part of the HTTP method 168 | 169 | 170 | ### HTTP Methods 171 | 172 | - GET fetch/find/search 173 | - POST create/submit 174 | - PUT create/replace 175 | - DELETE remove/delete 176 | - PATCH update/modify 177 | - OPTIONS get supported methods 178 | - HEAD get headers only / connectivity testing 179 | 180 | ### Idempotent Methods 181 | 182 | - GET 183 | - PUT 184 | - DELETE 185 | 186 | ### POST / PUT - differences in creating 187 | 188 | - `POST /products` 189 | - create a new product 190 | - new entity id is generated by the server 191 | - `PUT /products/123` 192 | - create a new product with id 123 193 | - client is specifying the id 194 | 195 | ### PUT / PATCH - differences in updating 196 | 197 | CASE A: 198 | Product ID: 123 199 | `{a: 10, b: 20}` 200 | 201 | CASE B: 202 | Product ID: 123 203 | `does not exist` 204 | 205 | - `PUT /products/123` 206 | - body: `{b: 30, c: 40}` 207 | - replace the product with id 123 or create it 208 | - client is sending the complete entity 209 | - CASE A: `{b: 30, c: 40}` 210 | - CASE B: `{b: 30, c: 40}` 211 | 212 | - `PATCH /products/123` 213 | - body: `{b: 30, c: 40}` 214 | - update the product with id 123 215 | - client can send partial entity 216 | - CASE A: `{a: 10, b: 30, c: 40}` 217 | - CASE B: `404 : product with id 123 does not exist` 218 | 219 | - Using `PATCH` for delta operations 220 | - `PATCH /products/123` 221 | ``` 222 | { 223 | "quantity": { "add": 10 } 224 | } 225 | ``` 226 | -------------------------------------------------------------------------------- /02-shopping-site/README.md: -------------------------------------------------------------------------------- 1 | # Shopping Site 2 | 3 | ## Entities 4 | 5 | ### User 6 | - id 7 | - created_at 8 | - updated_at 9 | - type (vendor, customer) 10 | 11 | ### Product 12 | - id // sku 13 | - group_id 14 | - created_at 15 | - updated_at 16 | - vendor_id reference(user.id) && user.type == vendor 17 | - quantity 18 | - variant 19 | - eg1: {size: XL, color: red} 20 | - eg2: {size: L, color: white} 21 | - marked_price // in INR, paise 22 | - sale_price // in INR, paise 23 | 24 | ### Cart 25 | - id 26 | - created_at 27 | - updated_at 28 | - user_id // reference(user.id) 29 | - // if global cart => set field unique 30 | 31 | ### Order 32 | - id 33 | - created_at 34 | - updated_at 35 | - user_id 36 | - status (created, processing, shipped, delivered, cancelled) 37 | - billing_address_id 38 | - shipping_address_id 39 | 40 | ### Payment 41 | - id 42 | - pg_txn_id 43 | - created_at 44 | - updated_at 45 | - method (credit_card, debit_card, net_banking, wallet, cash_on_delivery) 46 | - status (pending, success, failed) 47 | 48 | ### Address 49 | - id 50 | - created_at 51 | - updated_at 52 | - user_id 53 | - type (home, office, other) 54 | - line1 55 | - line2 56 | - city 57 | - state 58 | - country 59 | - pincode 60 | 61 | ### Mapping Entities 62 | 63 | #### Cart Product 64 | - cart_id 65 | - product_id 66 | - quantity 67 | 68 | #### Order Product 69 | - order_id 70 | - product_id 71 | - quantity 72 | - purchase_marked_price // in INR, paise 73 | - purchase_sell_price // in INR, paise 74 | 75 | #### Order Payment 76 | - order_id 77 | - payment_id 78 | 79 | 80 | ## Functional Requirements 81 | 82 | ### User 83 | - Guest can register as user (self-choice vendor vs customer) 84 | - Guest can login as user (if they have registered already) 85 | - User can logout 86 | - User can update their profile details 87 | - customer -> vendor allowed (vice-versa not allowed) 88 | - Addresses 89 | - Users can add addresses 90 | - Users can edit addresses 91 | - Users can delete addresses 92 | 93 | ### Product 94 | - Vendor can add product 95 | - Vendor can update product 96 | - Guests can list all products 97 | - filter by vendor 98 | - search by name 99 | - filter by price 100 | - Guests can list details of a single product 101 | 102 | ### Cart 103 | - User can add product to cart 104 | - User can change quantity of product in cart 105 | - User can remove product from cart 106 | 107 | ### Order 108 | - User can place order 109 | - User can select address for billing 110 | - User can select address for shipping 111 | - User can fetch all orders 112 | - sort by created 113 | - User can fetch order by order_id 114 | - User can cancel order 115 | - order status should be `created` or `processing` 116 | 117 | ### Payment 118 | - User can pay for order 119 | - User can select payment method 120 | - User can see payment status 121 | 122 | 123 | ### Payment Flow 124 | 125 | ![](./payment_flow.png) -------------------------------------------------------------------------------- /02-shopping-site/payment_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/championswimmer/REST_API_Design_2024-03-16/cc0fdc1184f3bbd2ce08bcf4fd97c3b599f1d92b/02-shopping-site/payment_flow.png -------------------------------------------------------------------------------- /03-social-media-site/API.md: -------------------------------------------------------------------------------- 1 | # API - Social Media Site 2 | 3 | Base URL: `https://api.chirper.com/v1/` 4 | 5 | **Authentication** 6 | 7 | Headers: 8 | ```http 9 | Authorization: Token 10 | ``` 11 | 12 | ## Generic Responses 13 | 14 | ### Success 15 | 16 | ```json 17 | { 18 | "status": "success", 19 | "code": 201, 20 | "message": "Post created successfully", 21 | "data": {}, 22 | "meta": { 23 | "page": 1, 24 | "limit": 10, 25 | "total": 100 26 | } 27 | } 28 | ``` 29 | 30 | 31 | ### Errors 32 | 33 | ```json 34 | { 35 | "status": "error", 36 | "code": 400, 37 | "message": "Bad Request", 38 | "data": {}, 39 | "meta": { 40 | } 41 | } 42 | ``` 43 | 44 | ## Endpoints 45 | 46 | ### Users 47 | 48 | #### `POST /users` - Register/signup user 49 | 50 | **Responses** 51 | 52 | - 201 - Created 53 | - 409 - Conflict (User already exists) 54 | - 400 - Bad Request (Validation error) 55 | 56 | #### `POST /users/login` - Login user 57 | 58 | **Responses** 59 | 60 | - 200 - OK 61 | - 400 - Bad Request (Validation error) 62 | - 401 - Unauthorized (Invalid Credentials) 63 | - 404 - Not found (User not found) 64 | 65 | #### `GET /users` - Search users 66 | - `?display_name=Arnav` // contains or like %Arnav% 67 | - `?username=arnav` // contains or like %arnav% 68 | 69 | **Responses** 70 | 71 | - 200 - OK 72 | - 401 - Unauthorized (Invalid credentials) 73 | - 404 - Not Found (User not found) 74 | 75 | #### `GET /users/{@username/userid}` - Get user profile 76 | 77 | **Responses** 78 | 79 | - 200 - OK 80 | - 401 - Unauthorized (Invalid credentials) 81 | - 404 - Not Found (User with `userid` not found) 82 | 83 | #### `PATCH /users/me` 🔐 - Update user profile 84 | 85 | **Responses** 86 | 87 | - 202 - Accepted (Queued, profile update will likely succeed) 88 | - 400 - Bad Request (Validation error) 89 | - 401 - Unauthorized (Invalid Credentials) 90 | 91 | #### `PUT /users/{username}/follow` 🔐 - Follow a user 92 | 93 | **Responses** 94 | 95 | - 200 - OK 96 | - 400 - Bad Request (Validation error) 97 | - 401 - Unauthorized (Invalid Credentials) 98 | 99 | #### `DELETE /users/{username}/follow` 🔐 - Un/Follow a user 100 | 101 | **Responses** 102 | 103 | - 200 - OK (Unfollow successful) 104 | - 202 - Accepted (Queued, Will likely succeed) 105 | - 204 - No Content (Unfollow successful, no entity) 106 | - 400 - Bad Request (Validation error) 107 | - 401 - Unauthorized (Invalid Credentials) 108 | - 404 - Not Found (User with `username` not found) 109 | 110 | ### Posts 111 | 112 | #### `GET /users/{username}/posts` - Get all posts of a user 113 | - `?sort=created_at` // sort by created_at 114 | - `?sort=likes` // sort by likes 115 | - `?page=1&limit=10` // pagination 116 | 117 | **Responses** 118 | - `200 OK` - Success 119 | - `404 Not Found` - User not found 120 | 121 | #### `GET /posts` - Get all posts 122 | - `?display_name=Arnav` // filter by name 123 | - `?sort=created_at` // sort by created_at 124 | - `?sort=likes` // sort by likes 125 | - `?page=1&limit=10` // pagination 126 | - `?only_following=true` 🔐 // only posts of people I follow 127 | - `?reply_to_post_id=123` // only replies to post with id = 123 128 | - `?quoted_post_id=123` // only quotes of post with id = 123 129 | - `?is_retweet=true` // only retweets (body = null) 130 | 131 | **Responses** 132 | - `200 OK` - Success 133 | - Can be empty array `[]` in data 134 | - 401 - Unauthorized (Invalid credentials) 135 | 136 | #### `POST /posts` 🔐 - Create a new post 137 | - body : `{body, ...}` 138 | - body : `{media: [media_id, ...], ...}` if media is present 139 | - body : `{reply_to_post_id}` - if it is a reply 140 | - body : `{quoted_post_id}` - if it is a quote 141 | 142 | **Responses** 143 | 144 | - 200 - OK 145 | - 201 - Post created 146 | - 401 - Unauthorized (Invalid credentials) 147 | 148 | #### `GET /posts/{postid}` - Get a post 149 | 150 | **Responses** 151 | 152 | - 200 - OK 153 | - 401 - Unauthorized (Invalid credentials) 154 | - 404 - Not Found (Post not found) 155 | 156 | #### `PUT /posts/{postid}/like` 🔐 - Like a post 157 | 158 | **Responses** 159 | 160 | - 200 - OK 161 | - 202 - Accepted 162 | - 401 - Unauthorized (Invalid credentials) 163 | - 404 - Not Found (Post not found) 164 | 165 | #### `DELETE /posts/{postid}/like` 🔐 - Unlike a post 166 | 167 | **Responses** 168 | 169 | - 200 - OK (Unlike successful) 170 | - 202 - Accepted (Queued, Will likely succeed) 171 | - 204 - No Content (Unlike successful, no entity) 172 | - 400 - Bad Request (Validation error) 173 | - 401 - Unauthorized (Invalid Credentials) 174 | - 404 - Not Found (Post with `postid` not found) 175 | 176 | #### `GET /posts/{postid}/likes` - Get all users who have liked 177 | 178 | **Responses** 179 | 180 | - 200 - OK 181 | - 401 - Unauthorized (Invalid credentials) 182 | - 404 - Not Found 183 | 184 | ### Media 185 | 186 | #### `POST /media` 🔐 - Upload media 187 | - body : `` // media file : multipart/streaming 188 | 189 | **Responses** 190 | 191 | - 200 - OK 192 | - 401 - Unauthorized (Invalid credentials) 193 | - 415 - Unsupported Media Type 194 | 195 | #### `DELETE /media/{mediaid}` 🔐 - Delete media 196 | 197 | **Responses** 198 | 199 | - 200 - OK 200 | - 202 - Accepted 201 | - 401 - Unauthorized (Invalid credentials) 202 | - 404 - Not Found (Media not found) 203 | 204 | ## Notes 205 | 206 | ### REST API Principles 207 | 208 | - Entities/Resources 209 | - goes into URL path 210 | - nouns 211 | - /users, /posts 212 | - when referring to "collections" -> always use plural 213 | - Actions / Operations 214 | - use the HTTP method for this 215 | - verbs 216 | - eg: create, update, delete 217 | - POST, PUT, PATCH, DELETE 218 | - Qualifiers / Filters / Modifiers 219 | - /posts?liked_by={userid} 220 | - /posts?created_before={timestamp}&created_after={timestamp} 221 | - /users?has_image=true 222 | 223 | ### HTTP Methods 224 | 225 | - GET read/find/search 226 | - POST create/submit 227 | - PUT create/replace 228 | - PATCH update/modify 229 | - DELETE delete/remove 230 | - OPTIONS get allowed methods 231 | - HEAD status/connectivity checks 232 | 233 | ### POST vs PUT for creating a resource 234 | 235 | `POST /posts` 236 | - body : `{body, media, ...}` 237 | - creates a new post 238 | - server generates the id for this post 239 | - response will have the new id 240 | 241 | `PUT /posts/123` 242 | - body : `{body, media, ...}` 243 | - creates a new post with id = 123 244 | - client is specifying the id for this post 245 | - will replace post with id = 123 if it exists 246 | 247 | ### PUT vs PATCH for updating a resource 248 | 249 | CASE A: Post with id = 123 exists 250 | `{ a: 10, b: 20 }` 251 | 252 | CASE B: Post with id = 123 does not exist 253 | 254 | `PUT /posts/123` 255 | - body : `{ b: 30, c: 40 }` 256 | - replaces the post with id = 123 with `{ b: 30, c: 40 }` 257 | - CASE A: `{ b: 30, c: 40 }` 258 | - CASE B: `{ b: 30, c: 40 }` 259 | 260 | `PATCH /posts/123` 261 | - body : `{ b: 30, c: 40 }` 262 | - CASE A: `{ a: 10, b: 30, c: 40 }` 263 | - CASE B: 404 Not Found -------------------------------------------------------------------------------- /03-social-media-site/README.md: -------------------------------------------------------------------------------- 1 | # Social Media Site 2 | Basic features of Twitter/Mastodon type website. 3 | Posts, reposts, reply-posts, quotes, likes, follows 4 | Posts can have 1 media 5 | 6 | ## Entities 7 | 8 | ### User 9 | - id 10 | - created_at 11 | - updated_at 12 | - username // unique 13 | - display_name // non-unique 14 | - email 15 | - password 16 | - image_id // references (media.id) 17 | - bio 18 | 19 | 20 | ### Post 21 | - id 22 | - created_at 23 | - updated_at 24 | - deleted_at 25 | - user_id // references (user.id) 26 | - body 27 | - reply_to_post_id // references (post.id) 28 | - reply_parent_post_id // references (post.id) 29 | - quoted_post_id // references (post.id) 30 | - likes_count // refresh from post_like table 31 | - retweets_count // refresh from post table 32 | - replies_count // refresh from post table 33 | 34 | ### Media 35 | - id 36 | - created_at 37 | - updated_at 38 | - deleted_at 39 | - media_type // image, video, gif 40 | - media_url // url 41 | 42 | ### Mapping Tables 43 | 44 | #### User Follow 45 | - id 46 | - created_at 47 | - updated_at 48 | - follower_id 49 | - followee_id 50 | 51 | #### Post Media 52 | - id 53 | - created_at 54 | - updated_at 55 | - post_id 56 | - media_id 57 | 58 | #### Post Like 59 | - id 60 | - created_at 61 | - post_id 62 | - user_id 63 | 64 | ## Functional Requirements 65 | 66 | ### User 67 | - Guest can register themselves as an user 68 | - Guest can login (if they had registered themselves) 69 | - Guests can see profile of users 70 | - Guests can search for users by display name 71 | - - Guests can search for users by username 72 | - Users can update their profile 73 | - Users can (un)follow other users 74 | 75 | ### Post 76 | - Guests can see all posts 77 | - Sort by created_at 78 | - Sort by likes 79 | - (has to be pagniated) 80 | - Filter by userid 81 | - Users can see all posts by people they follow 82 | - Users can create a post 83 | - Users can attach a media in a post 84 | - Users can reply to a post 85 | - Users can quote a post 86 | - Quotes may/maynot have a body (i.e. simply retweet) 87 | - Users can (un)like a post 88 | - Users can delete their own post 89 | - Guests can see who has liked a post 90 | - (has to be pagniated) 91 | - Guests can see who has retweeted/quoted a post 92 | - (has to be pagniated) 93 | - Guests can see all replies (including nested replies) to a post 94 | - (has to be pagniated) 95 | 96 | ### Media 97 | - Users can upload media 98 | - Users can delete their own media 99 | 100 | 101 | ## Notes 102 | 103 | ![](./post_relationship.png) 104 | 105 | ![](./m-n-relationship.png) -------------------------------------------------------------------------------- /03-social-media-site/m-n-relationship.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/championswimmer/REST_API_Design_2024-03-16/cc0fdc1184f3bbd2ce08bcf4fd97c3b599f1d92b/03-social-media-site/m-n-relationship.png -------------------------------------------------------------------------------- /03-social-media-site/post_relationship.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/championswimmer/REST_API_Design_2024-03-16/cc0fdc1184f3bbd2ce08bcf4fd97c3b599f1d92b/03-social-media-site/post_relationship.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # REST API Workshop 2 | --------------------------------------------------------------------------------