Kotkogram is like Instagram... but for cats!
The REST API powers the app by providing users and data service. Data is stored in MongoDB Atlas.
For educational purposes only!
- You need local instance of MongoDB
- Install dependecies:
npm i
- Start server on port 5000:
npm i
- Enjoy!
{
code: number,
message: string,
data: { [key: string]: any } | undefined,
errors: string[] | undefined,
}
- Route:
/api
returns REST API meta data.
Some of the endpoints require for you to make authorized requests (marked below). To do so, you need to login first and the API will return a jwt token in http-only cookie. The browser automatically will attach the cookie with every request.
GET /api/users
- Returns endpoints.
POST /api/users/signup
- Create new user. For User model check below. Returns created user data and a jwt token in http-only cookie. If error occurs, returnsstatus 400
.
{
username: string,
firstName: string,
lastName: string,
password: string, // hashed on save
description: string, // optional
imageUrl: string, // optional
}
POST /api/users/login
- Log in user withusername
andpassword
. Returns user data and a jwt token in http-only cookie. If error occurs, returnsstatus 401
.
{
username: string,
password: string,
}
DELETE /api/users/logout
- Clears jwt cookie. Authorized request!
/api/users/me
- Returns user data if jwt token is valid. Otherwise returnsstatus 401
orstatus 403
. Authorized request!
GET /api/users/:_id
- Returns data for user with matching ID. Limited to publicly available information. If no data is found, returnsstatus 404
. Authorized request!
PATCH /api/users/:_id
- Edit user data. For owners only. If error occurs, returnsstatus 400
. Username cannot be edited. Password edit is on another endpoint. Authorized request!
{
"firstName": string, // optional
"lastName": string, // optional
"description": string, // optional
"imageUrl": string, // optional
}
PATCH /api/users/:_id/password
- Edit user password. For owners only. If error occurs, returnsstatus 409
. Authorized request!
{
"oldPassword": string,
"newPassword": string,
}
POST /api/users/:_id/password
- Check if password is valid. For owners only. If error occurs, returnsstatus 409
. Authorized request!
{
"password": string,
}
POST /api/users/isunique
- Check if username is unique. If error occurs, returnsstatus 409
.
{
"username": string,
}
POST /api/users/:_id/follow
- Follow user._id
param is of the user you wish to follow. If error occurs, returnsstatus 400
. Authorized request!
Basic structure: '/api/collections/:collection/:_id'
GET /api/collections/:collection
- Returns array of objects. Returns status 404 if there are no results.GET /api/collections/:collection/:id
- Returns an object. Returns status 404 if there are is no result.
POST /api/collections/:collection
- Creates new item in the chosen collection. Returns the created item. Authorized request!
PATCH /api/collections/:collection/:_id
- Update item with matching ID. Returns the updated item. Authorized request!
DELETE /api/collections/:collection/:_id
- Delete item with matching ID. Returnsstatus 202
. Authorized request!
POST /api/collections/:collection/:_id/like
- Like or remove like (if its already liked) for item in collection. User ID is automatically extracted from jwt cookie, so there is no need to put anything in request body. Authorized request!
You can put multiple queries of the same type.
Example:
GET /api/collections/posts/62cd7b659032c071e10e4f8e?populate=owner&populate=post
Append URL encoded string sortBy={property asc/desc}
to the query parameters to sort by property name in ascending (asc
) or descending (desc
) order.
Example:
(unencoded) /api/collections/posts?sortBy=createdAt desc
GET /api/collections/posts?sortBy=createdAt%20desc
Append URL encoded string where={property=value}
to the query parameters. Only full matches will be returned.
Example:
(unencoded) /api/collections/posts?where=owner=8f414b4fab394d36bedb2ad69da9c830
GET /api/collections/posts?where=owner%3D%228f414b4fab394d36bedb2ad69da9c830%22
By default the service returns 10 entries.
Append page={pageNumber}&pageSize={entries}
to the query parameters, where {pageNumber}
is the number of entries to skip and {entries}
is the number of entries to return.
Example: Second page of entries from the answers collection, assuming 10 entries per page:
GET /api/collections/posts?page=2&pageSize=10
Append populate={property}
to the query parameters, where {property}
is the property you want to populate with data.
Example:
GET /api/collections/posts/62cd7b659032c071e10e4f8e?populate=owner
Append count=true
to the query parameters. It can be combined with SEARCH
query.
Example:
GET /api/collections/posts?count=true
Append select={property}
to the query parameters, where {property}
is the property you want to select. You can add multiple properties, separated by space.
Example:
GET /api/collections/answers?select=owner
{
username: string,
firstName: string,
lastName: string,
password: string, // hashed on save
description: string, // optional
imageUrl: string, // optional
following: ObjectId[], ref: 'User'
role: ['user', 'moderator', 'admin']
}
{
imageUrl: string,
description: string,
owner: ObjectId, ref: 'User'
likes: ObjectId[], ref: 'User'
}
{
body: string,
owner: ObjectId, ref: 'User'
post: ObjectId, ref: 'Post'
}