New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce /api/profile_images/:username endpoint #10547
Introduce /api/profile_images/:username endpoint #10547
Conversation
This endpoint receives either an user or organization username as input via the URL path and returns the profile image information for that user/orgnization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, left a few notes! :-)
| module Api | ||
| module V0 | ||
| class ProfileImagesController < ApiController | ||
| before_action :set_cache_control_headers, only: %i[show] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you set the caching headers, you also need a way to destroy that cache, so you need the surrogate keys for the resource, which in this case it could be a user or an org.
I'm not sure it's worth to cache this endpoint though and in general I think we should lean towards caching endpoints that have either complex fetching queries or complex serialization structures.
This have neither, so I'd lean towards removing the cache altogether
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, didn't looked into this with much attention - giving the method a quick glance I got the idea that it was just setting a 1 day cache control header (I didn't even realize that there was a cache invalidation mechanism also put in place).
Thanks for noticing this, I've removed the action. 馃憦
| @user ||= User.select(:id, :profile_image) | ||
| .find_by(username: params[:username], registered: true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
love that you thought about the registered users. Can I suggest making it even more explicit by using the .registered scope?
Something like
User.registered.select().find_by()| json.type_of "profile_image" | ||
|
|
||
| json.profile_image Images::Profile.call(@profile_image_url, length: 640) | ||
| json.profile_image_90 Images::Profile.call(@profile_image_url, length: 90) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I read your doubts in the description but I think the serialization is simple enough to be effective, if we need more versions of the image we can add them but this closely resembles what we send back with the user or organization representations in their own partials.
I would add a key that should help the client: is this the image of a user or an org?
Maybe:
{
"type_of": "profile_image",
"image_of: "user"
...
}what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup I tinkered a bit with the idea of embedding the owner somehow on the response:
{
...
"owner": {
"type_of": "user" | "organization",
...
}
}But given the use case (simply retrieving the profile image), it seemed an overkill tbh. I also tinkered with the possibility of trying to model this using OpenAPI Links, but I couldn't find a way to do so. 馃槃
Anyway I agree and I ended up implementing your suggestion. 馃憤
Adapts the response according to the review comments: 1. Removes the cache directives 1. Tweaks how the user query is being done 1. Adds a `image_of` property to the response
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works well, thanks @diogoosorio!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Looks like a merge conflict needs to be fixed but then this should be ready to go
|
I fixed the conflict by upping the file version value to |
* Documents the new /profile-images/:username API endpoint * Introduces the /api/profile_images/:username endpoint This endpoint receives either an user or organization username as input via the URL path and returns the profile image information for that user/orgnization. * Updates the /api/profile_images/:username response Adapts the response according to the review comments: 1. Removes the cache directives 1. Tweaks how the user query is being done 1. Adds a `image_of` property to the response * Bump API version Co-authored-by: rhymes <rhymes@hey.com> Co-authored-by: Molly Struve <mollylbs@gmail.com>
What type of PR is this? (check all applicable)
Description
This PR aims to introduce the operation
GET /api/profile_images/:usernameto the API.I struggled a bit with what the contract for the operation should be (as this isn't a "resource" per se), I ended up keeping it simple and re-using the structure I saw throughout the rest of the API, when dealing with profile images:
{ "type_of": "profile_image", "profile_image": "/uploads/organization/profile_image/be5e87e9-5b77-40ea-81e8-dd10c6d01146.png", "profile_image_90": "/uploads/organization/profile_image/be5e87e9-5b77-40ea-81e8-dd10c6d01146.png" }Having said that, I'm happy to refactor the contract to whatever the maintainers believe it to be the correct way to represent a profile image in this endpoint - I just ask for concrete example of what the response's payload should look like 馃槃 .
Related Tickets & Documents
#10132
QA Instructions, Screenshots, Recordings
curl "http://localhost:3000/api/profile_images/:username"Added tests?
Added to documentation?