We are developing a REST API that serves as a backend for our iOS and Android apps as well as an AngularJS web app. In order to optimize performance, we have to provide images in a variety of resolutions. I am looking for guidance around how to provide the client with the correct image URL for its device resolution. I can imagine three possibilities:
1. The client has logic to determine the resolution dependent URL for an image.
The REST API returns a canonical image URL:
{
"user": {
"id": 1,
"image_profile": "https://cdn.mydomain.com/abcd.jpg"
}
}
The client then knows how to change the URL to get the needed resolution.
E.g. something like: https://cdn.mydomain.com/[email protected]
or https://cdn.mydomain.com/w_100,h_100/abcd.jpg
.
This is based on the idea, that the client knows exactly where the image will go and in what size and resolution it is needed. The cons are more logic on the client. This could for example be implemented with a service such as http://cloudinary.com/.
2. The server provides different versions for each image.
The REST API returns all available image URLs:
{
"user": {
"id": 1,
"image_profile": {
"url": "https://cdn.mydomain.com/abcd.jpg",
"versions": {
"mhdpi": "https://cdn.mydomain.com/abcd_mhdpi.jpg",
"lhdpi": "https://cdn.mydomain.com/abcd_lhdpi.jpg",
"2x": "https://cdn.mydomain.com/[email protected]",
"web": "https://cdn.mydomain.com/abcd_web.jpg"
}
}
}
}
In this solution the client needs less logic and the implementation of resizing the images is independent of the client. Responses become a bit polluted.
3. The server returns the right image automatically based on the user agent (or any other parameter)
The client could specify its expected resolution in a user agent header (or could append something like ?resolution=2x
to every request.
For an example user agent of iPhone 5S (iOS 7.1)
the API would automatically return the right image:
{
"user": {
"id": 1,
"image_profile": "https://cdn.mydomain.com/[email protected]"
}
}
The client is oblivious to the resolution problem but this approach makes responses less cacheable and feels the most like magic.
Can you please suggest other solutions, elaborate on the pros and cons of the ones presented and point me to some resources about how the well-known APIs handle this problem?
The second option fits closest with a RESTful API design, with the inherent benefits that come with it.
Taking each in turn:
1. Client altering the URL has the risk that you'll break the clients if you ever need to change the image identifier URL format for any reason.
2. Server provides multiple versions is best aligned with a RESTful approach, with the principle benefit that changing the URL format will not break existing clients. It also allows for extensibility which is potentially self descriptive and machine readable (with a small change) like this:
{
"user": {
"id": 1,
"image_profile": {
"url": "https://cdn.mydomain.com/abcd.jpg",
"versions": {
"100": "https://cdn.mydomain.com/abcd_mhdpi.jpg",
"150": "https://cdn.mydomain.com/abcd_lhdpi.jpg",
"300": "https://cdn.mydomain.com/[email protected]",
"72": "https://cdn.mydomain.com/abcd_web.jpg"
}
}
}
}
...i.e. you could redefine the identifier as a "DPI" figure or something similar. I don't know how advanced your client applications are; but potentially they could look for the numerical "nearest match" of DPI for the screen size in use. You could then insert additional resolutions in future accordingly.
3. Server uses agent string avoids the risks of option 1; but the client application itself is best placed to make the decision on resolution because it knows more about the context.
Option 2 doesn't restrict you in any way; and is also the most resilient to avoiding breaking changes in future.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With