openapi: 3.0.2 info: title: WASAPhoto API description: |- Keep in touch with your friends by sharing photos of special moments, thanks to WASAPhoto! You can upload your photos directly from your PC, and they will be visible to everyone following you. version: "3.0" tags: - name: login description: Login API - name: username description: Operations related to username - name: followers description: Operations related to followers - name: likes description: Operations related to likes - name: bans description: Operations related to bans - name: profile description: Operations related to user profiles - name: photos description: Operations related to photos - name: comments description: Operations related to comments - name: stream description: Operations related to the user stream paths: /session: post: tags: ["login"] summary: Logs in the user description: |- If the user does not exist, it will be created, and an identifier is returned. If the user exists, the user identifier is returned. operationId: doLogin requestBody: $ref: "#/components/requestBodies/userDetails" responses: '201': description: User log-in action successful. content: application/json: schema: $ref: "#/components/schemas/uid_object" example: user_id: "123e4567-e89b-12d3-a456-426655440000" /users/{user_id}/username: put: tags: ["username"] summary: Updates the username description: Changes the username of the user with the given one. operationId: setMyUserName parameters: - name: user_id in: path schema: $ref: "#/components/schemas/uid" required: true description: The user ID of the user to change the username to. security: - BearerAuth: [] requestBody: $ref: "#/components/requestBodies/userDetails" responses: '204': description: Update username action successful. '409': description: The chosen username is already taken by another users. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Username already taken" '404': description: The user does not exist. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "User not found" /users/{user_id}/followers: get: tags: ["followers"] summary: Gets user's followers description: Get the followers list of the user operationId: getUserFollowers security: - BearerAuth: [] parameters: - name: user_id in: path schema: $ref: "#/components/schemas/uid" required: true description: The user ID of the user to follow. responses: '200': description: Returns the user list content: application/json: schema: type: array description: The list of followers. minItems: 0 maxItems: 100 items: $ref: "#/components/schemas/uid_name" example: - user_id: "123e4567-e89b-12d3-a456-426655440000" name: "Maria" - user_id: "123e4567-e89b-12d3-a456-426655440001" name: "Filippo" '404': description: The user does not exist. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "User not found" /users/{user_id}/following: get: tags: ["followers"] summary: Gets following users description: Get the users that a user is following operationId: getUserFollowing security: - BearerAuth: [] parameters: - name: user_id in: path schema: $ref: "#/components/schemas/uid" required: true description: The user ID of the user to follow. responses: '200': description: Returns the user list content: application/json: schema: type: array minItems: 0 maxItems: 100 description: The list of users that the user is following. items: $ref: "#/components/schemas/uid_name" example: - user_id: "123e4567-e89b-12d3-a456-426655440000" name: "Maria" - user_id: "123e4567-e89b-12d3-a456-426655440001" name: "Filippo" '404': description: The user does not exist. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "User not found" /users/{user_id}/followers/{follower_uid}: parameters: - name: user_id in: path schema: $ref: "#/components/schemas/uid" required: true description: The ID of the user to follow. - name: follower_uid in: path schema: $ref: "#/components/schemas/uid" required: true description: The follower's user ID. put: tags: ["followers"] summary: Follows a user description: Starts following a user operationId: followUser security: - BearerAuth: [] responses: '201': description: Follow user action successful. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Success" '403': description: The user has no permission perform this action. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Forbidden" '404': description: The resource does not exist. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" '400': description: Trying to follow a user that does not exist. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "User not found" delete: tags: ["followers"] summary: Unfollows a user description: Stops following a user operationId: unfollowUser security: - BearerAuth: [] responses: '204': description: Unfollow user action successful. '404': description: The user is not followed by follower_uid, or the user does not exist. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "User not found" /users/{user_id}/bans/{ban_uid}: parameters: - name: user_id in: path schema: $ref: "#/components/schemas/uid" required: true description: The user ID of the banning user. - name: ban_uid in: path schema: $ref: "#/components/schemas/uid" required: true description: The user ID of the banned user. put: tags: ["bans"] summary: Bans a user description: Add a user to the list of banned users of the user. operationId: banUser security: - BearerAuth: [] responses: '201': description: Ban user action successful. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Success" '204': description: The user is already banned. '403': description: The user has no permission to perform this action. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Forbidden" '404': description: The user does not exist. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "User not found" delete: tags: ["bans"] summary: Unbans a user description: Removes a ban from the list of banned users of the user. operationId: unbanUser security: - BearerAuth: [] responses: '204': description: Unban user action successful. '403': description: The user has no permission to perform this action. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Forbidden" '404': description: The user is not banned by the user. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "User not found" /users/{user_id}/photos/{photo_id}/likes: get: tags: ["likes"] summary: Gets photo likes description: Get the list of users liking a photo operationId: getPhotoLikes security: - BearerAuth: [] parameters: - name: user_id in: path schema: $ref: "#/components/schemas/uid" required: true description: The ID of the author of the photo. - name: photo_id in: path schema: $ref: "#/components/schemas/photo_id" required: true description: The ID of the photo. - name: limit in: query schema: $ref: "#/components/schemas/limit" description: The number of elements to show. required: false - name: start_index in: query schema: $ref: "#/components/schemas/start_index" description: The starting offset. required: false responses: '200': description: Returns the user list content: application/json: schema: type: array minItems: 0 maxItems: 100 description: An array of users liking the photo. items: $ref: "#/components/schemas/uid_name" example: - user_id: "123e4567-e89b-12d3-a456-426655440000" name: "Maria" - user_id: "123e4567-e89b-12d3-a456-426655440001" name: "Filippo" '404': description: The user or the photo does not exist. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" /users/{user_id}/photos/{photo_id}/likes/{liker_uid}: parameters: - name: user_id in: path schema: $ref: "#/components/schemas/uid" required: true description: The ID of the author of the photo. - name: liker_uid in: path schema: $ref: "#/components/schemas/uid" required: true description: The ID of the user who likes the photo. - name: photo_id in: path schema: $ref: "#/components/schemas/photo_id" required: true description: The ID of the photo. put: tags: ["likes"] summary: likes a Photo description: Adds a like to a photo. operationId: likePhoto security: - BearerAuth: [] responses: '201': description: Like photo action successful. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Success" '204': description: The user already likes the photo. '403': description: The user has no permission to perform this action. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Forbidden" '404': description: Resource not found (or the author of the photo has banned the authorized user). content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" '400': description: Bad URI (maybe liker_uid is invalid). content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Bad photo_id" delete: tags: ["likes"] summary: Unlikes a photo description: Removes a like from a photo operationId: unlikePhoto security: - BearerAuth: [] responses: '204': description: Unlike photo action successful. '404': description: The user or photo does not exists, or the user is not liking the photo. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" /users: get: tags: ["search"] summary: Search users by username description: Search users whose username contains the given string. operationId: searchUsers security: - BearerAuth: [] parameters: - name: query in: query schema: $ref: "#/components/schemas/name" required: true description: The username to search. - name: limit in: query schema: $ref: "#/components/schemas/limit" description: The number of elements to show. required: false - name: start_index in: query schema: $ref: "#/components/schemas/start_index" description: The starting offset. required: false responses: '200': description: Returns the user list content: application/json: schema: type: array minItems: 0 maxItems: 100 description: An array of users whose username contains the given string. items: $ref: "#/components/schemas/search_result" example: - user_id: "123e4567-e89b-12d3-a456-426655440000" name: "Maria" followed: false banned: false - user_id: "123e4567-e89b-12d3-a456-426655440001" name: "Filippo" followed: true banned: false '404': description: No user found. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" '400': description: Some parameters are malformed. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Invalid start_index or limit value" '401': description: The user is not logged in. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Unauthorized" /users/{user_id}: get: tags: ["profile"] summary: Returns user profile description: Returns the profile of a user, including user's photos, followers, and following users. operationId: getUserProfile security: - BearerAuth: [] parameters: - name: user_id in: path schema: $ref: "#/components/schemas/uid" description: The user ID of the user to get the profile of. required: true responses: '200': description: Returns the profile details of the given user. content: application/json: schema: $ref: "#/components/schemas/user_profile" example: name: "Maria" followers: 25 following: 32 followed: true photos: 50 '404': description: User not found (or the authorized user is banned). content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" /users/{user_id}/photos: parameters: - name: user_id in: path schema: $ref: "#/components/schemas/uid" required: true description: The user ID of the user who uploads the photo. get: tags: ["photos"] summary: Returns user photos description: Returns the list of photos uploaded by a user. operationId: getUserPhotos security: - BearerAuth: [] parameters: - name: limit in: query schema: $ref: "#/components/schemas/limit" description: The number of elements to show. required: false - name: start_index in: query schema: $ref: "#/components/schemas/start_index" description: The starting offset. required: false responses: '200': description: Returns the user photos list content: application/json: schema: $ref: "#/components/schemas/user_photo_stream" '404': description: User not found (or the authorized user is banned). content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" '400': description: Some parameters are malformed. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Invalid start_index or limit value" post: tags: ["photos"] summary: Uploads a photo description: Uploads a photo in the gallery of the authorized user. operationId: uploadPhoto security: - BearerAuth: [] requestBody: content: image/jpg: schema: $ref: "#/components/schemas/image_jpg" responses: '201': description: Upload photo action successful. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource created" '404': description: User not found (or the authorized user is banned). content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" /users/{user_id}/photos/{photo_id}: parameters: - name: user_id in: path schema: $ref: "#/components/schemas/uid" description: The ID of the author of the photo. required: true - name: photo_id in: path schema: $ref: "#/components/schemas/photo_id" description: The ID of the photo. required: true get: tags: ["photos"] summary: Downloads a photo description: Returns the requested photo in binary format. operationId: getUserPhoto security: - BearerAuth: [] responses: '200': description: The requested photo in binary format. content: image/jpg: schema: $ref: "#/components/schemas/image_jpg" '404': description: User or photo not found (or the authorized user is banned by the author of the photo). content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" delete: tags: ["photos"] summary: Deletes a photo description: Deletes a photo in the gallery of the authorized user. operationId: deletePhoto security: - BearerAuth: [] responses: '204': description: Delete photo action successful. '401': description: The user has no permission to delete that photo. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Unauthorized" '404': description: User or photo not found. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" /users/{user_id}/photos/{photo_id}/comments: parameters: - name: user_id in: path schema: $ref: "#/components/schemas/uid" required: true description: The ID of the author of the photo. - name: photo_id in: path schema: $ref: "#/components/schemas/photo_id" required: true description: The ID of the photo. get: tags: ["comments"] summary: Gets photo comments description: Gets the list of comments of a photo operationId: getPhotoComments parameters: - name: limit in: query schema: $ref: "#/components/schemas/limit" description: The number of elements to show. required: false - name: start_index in: query schema: $ref: "#/components/schemas/start_index" description: The starting offset. required: false security: - BearerAuth: [] responses: '200': description: Returns the comments list content: application/json: schema: $ref: "#/components/schemas/comments" example: - user_id: "a1b2c3d4-e5f6-a7b8-c9d0-e1f2a3b4c5d6" name: "Maria" comment: "Nice photo!" comment_id: 1 date: "2020-11-20T12:00:00Z" - user_id: "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d" name: "John" comment: "I like it!" comment_id: 2 date: "2021-12-20T13:04:00Z" '404': description: The user or the photo does not exist. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" post: tags: ["comments"] summary: Comments a photo description: Adds a comment to a photo. operationId: commentPhoto security: - BearerAuth: [] requestBody: description: The comment to post. content: application/json: schema: $ref: "#/components/schemas/comment_request" example: comment: "Lovely!" responses: '201': description: Comment photo action successful. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Created" '404': description: The user or the photo does not exists (or the author of the photo has banned the authorized user). content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" /users/{user_id}/photos/{photo_id}/comments/{comment_id}: delete: tags: ["comments"] summary: Deletes a comment description: Deletes a photo in the gallery of the authorized user. operationId: uncommentPhoto security: - BearerAuth: [] parameters: - name: user_id in: path description: The ID of the author of the photo. schema: $ref: "#/components/schemas/uid" required: true - name: photo_id description: The ID of the photo. in: path schema: $ref: "#/components/schemas/photo_id" required: true - name: comment_id description: The ID of the comment to delete. in: path schema: $ref: "#/components/schemas/comment_id" required: true responses: '204': description: Delete comment action successful. '401': description: The user has no permission to delete that comment. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Unauthorized" '404': description: The comment does not exists. content: application/json: schema: $ref: "#/components/schemas/generic_response" example: status: "Resource not found" /stream: get: tags: ["stream"] summary: Returns user stream description: Returns the photo stream of the authorized user. operationId: getMyStream security: - BearerAuth: [] parameters: - name: limit in: query schema: $ref: "#/components/schemas/limit" description: The number of elements to show. required: false - name: start_index in: query schema: $ref: "#/components/schemas/start_index" description: The starting offset. required: false responses: '200': description: The photo stream. content: application/json: schema: $ref: "#/components/schemas/photo_stream" example: - user_id: "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d" name: "Federicus" photo_id: 157 upload_time: "2020-11-20T12:00:00Z" likes: 93 comments: 13 liked: true components: securitySchemes: BearerAuth: type: http scheme: bearer schemas: start_index: type: integer description: The starting offset. default: 0 limit: type: integer description: The number of elements to show. default: 15 uid_name: type: object properties: user_id: $ref: "#/components/schemas/uid" name: $ref: "#/components/schemas/name" uid_object: type: object description: The user identifier. properties: user_id: $ref: "#/components/schemas/uid" uid: type: string minLength: 36 maxLength: 36 description: The user ID. format: uuid pattern: '^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$' # RFC 4122 example: "1b4e28ba-2fa1-11d2-883f-0016d3cca427" name_object: type: object description: The username of the user. properties: name: $ref: "#/components/schemas/name" name: type: string description: The username of the user. example: Maria pattern: '^[a-zA-Z0-9_.]*$' minLength: 3 maxLength: 16 photo_id: type: integer description: The ID of the photo. example: 1527 comment_id: type: integer description: The ID of the comment. example: 3 upload_time: type: string format: date-time description: Upload time and date in RFC3339 format. minLength: 20 maxLength: 25 likes: type: integer example: 90 description: Number of likes. comments_n: type: integer example: 7 description: Number of comments on the photo. followers_n: type: integer example: 420 description: Number of followers. following_n: type: integer example: 69 description: Number of following users. like_status: type: boolean example: true description: Whether the user liked the photo. follow_status: type: boolean example: false description: Whether the user follows the other user. ban_status: type: boolean example: false description: Whether the user banned the other user. photos_n: type: integer example: 90 description: Number of photos. search_result: type: object properties: user_id: $ref: "#/components/schemas/uid" name: $ref: "#/components/schemas/name" followed: $ref: "#/components/schemas/follow_status" banned: $ref: "#/components/schemas/ban_status" user_profile: type: object description: The profile of the user. properties: name: $ref: "#/components/schemas/name" followers: $ref: "#/components/schemas/followers_n" following: $ref: "#/components/schemas/following_n" photos: $ref: "#/components/schemas/photos_n" followed: $ref: "#/components/schemas/follow_status" banned: $ref: "#/components/schemas/ban_status" user_photo_stream: type: array minItems: 0 maxItems: 100 description: An array of photos, upload time and likes. items: $ref: "#/components/schemas/user_photo_stream_item" user_photo_stream_item: type: object properties: photo_id: $ref: "#/components/schemas/photo_id" upload_time: $ref: "#/components/schemas/upload_time" likes: $ref: "#/components/schemas/likes" comments: $ref: "#/components/schemas/comments_n" liked: $ref: "#/components/schemas/like_status" photo_stream: type: array minItems: 0 maxItems: 100 description: An array of photos, author, upload time and likes. items: $ref: "#/components/schemas/photo_stream_item" photo_stream_item: type: object properties: user_id: $ref: "#/components/schemas/uid" name: $ref: "#/components/schemas/name" photo_id: $ref: "#/components/schemas/photo_id" upload_time: $ref: "#/components/schemas/upload_time" likes: $ref: "#/components/schemas/likes" comments: $ref: "#/components/schemas/comments_n" liked: $ref: "#/components/schemas/like_status" comments: type: array minItems: 0 maxItems: 100 description: An array of comments. items: $ref : "#/components/schemas/comment_item" comment_item: type: object properties: user_id: $ref: "#/components/schemas/uid" name: $ref: "#/components/schemas/name" comment: $ref: "#/components/schemas/comment" comment_id: $ref: "#/components/schemas/comment_id" date: $ref: "#/components/schemas/upload_time" comment_request: description: The comment to post. type: object properties: user_id: $ref: "#/components/schemas/uid" comment: $ref: "#/components/schemas/comment" comment: minLength: 1 maxLength: 255 pattern: "^(.){1,255}$" # everything except newlines type: string example: "What a lovely picture! 😊" description: The comment's text image_jpg: description: The photo to upload. type: string format: binary minLength: 1 maxLength: 10485760 # 10 MB pattern: "((.|\n)*)" # this accepts everything generic_response: type: object description: An object representing a success. properties: status: type: string minLength: 1 maxLength: 255 pattern: ".*" description: The status of the request. example: "Success" requestBodies: userDetails: description: User details content: application/json: schema: $ref: "#/components/schemas/name_object" example: name: "Maria" required: true