Skip to end of metadata
Go to start of metadata

This page describes some design decisions behind user photo.

Requirements:

  • In a buddy request message, the user photo should be shown
  • In all messages from buddies the user photo should be shown

Questions/answers:

  • Q: In what format should the photo be uploaded?
  • A: The default is multipart/form-data uploads, so let's implement this. We expect that the app will resize the photo to prevent large uploads. We at least use a separate upload/download endpoint and do not include it in the user JSON, because it is a larger request so good to send/receive separately.
  • Q: Should it be possible to upload a photo before creating the account (so before the user id is known)? Or only after the account has been submitted?
  • A: Not necessary. Otherwise it is an easy target for DOS attacks.

There are multiple possible flavors for the REST API between which we have to choose. These are explained below.

Option 1 - Attached to user

The path for the photo link is a subresource of the user.

PathMethodDescriptionPassword required?
/users/{userID}/photoPUTUpload a new photo(tick)
/users/{userID}/photoDELETERemove the current photo(tick)
/users/{userID}/photoGETDownload your own photo(tick)
/users/{userID}/buddies/{buddyID}/photoGETDownload the photo of a buddy(tick)


Pro/con:

  • (minus) Cannot be used until the user created their account.
  • (plus) Makes the one-to-one relation of user to photo easy to maintain
  • (minus) Fetching a photo requires authentication, so standard HTTP proxy caching cannot be used
  • (minus) The photo is not accessible from a buddy request message/user delete message/buddy disconnect message
  • (plus) User photo can be removed immediately when updated/deleted

Option 2 - Detached

PathMethodDescriptionPassword required?
/userPhotos/POST

Upload a new photo

(warning) Can be accessed unauthorized, so DOS prevention should be enabled

(error)
/userPhotos/{userPhotoId}GET

Download a photo by ID

(error)
/userPhotos/{userPhotoId}DELETE

Remove a photo by ID

(question) How to authorize for this action? Send the password header and retrieve the attached user ID from the UserPhoto entity?

(question)
EXISTING /users/POST

Allow to link a photo on user account creation by URL in the _links section

(tick)
EXISTING /users/{userID}PUTAllow to link/unlink a photo on user update by URL in the _links section(tick)

Pro/con:

  • (minus) Authorization gets more complicated
  • (minus) DOS prevention required
  • (plus) Can be used before user account creation has finished
  • (plus) Fetching a photo does not require authentication, so standard HTTP proxy caching can be used
  • (minus) User photo can not be cleaned up immediately when updated/deleted, because the app may have cached messages which have the link to the photo before update/delete
  • (plus) User photo can still be accessed for some time from user deleted messages/buddy disconnect messages

Option 3 - Attached to user, separately retrievable BEST OPTION

PathMethodDescriptionPassword required?
/users/{userID}/photoPUTUpload a new photo(tick)
/users/{userID}/photoDELETERemove the current photo(tick)
/userPhotos/{userPhotoId}GETDownload a photo.(error)
EXISTING /users/{userID}GETFetch the photo link when fetching the user (whether buddy or own user)(tick)

Pro/con:

  • (minus) Cannot be used until the user created their account
  • (plus) Makes the one-to-one relation of user to photo easy to maintain
  • (plus) Fetching a photo does not require authentication, so standard HTTP proxy caching can be used
  • (plus) No need for DOS-prevention mechanism
  • (minus) User photo can not be cleaned up immediately when updated/deleted, because the app may have cached messages which have the link to the photo before update/delete
  • (plus) User photo can still be accessed for some time from user deleted messages/buddy disconnect messages
  • No labels