Introducing API version 5
Introduction
We've just released API version 5, which contains many enhancements and new features. Since the introduction of API version 4, our website traffic has tripled. Nowadays we handle 6 million requests per hour. It's an accomplishment that we're very proud of, handling such large amounts of traffic is a great challenge. This service would not have been reliable without the CDN provided by Cloudflare and effective software (such as nginx and libvips).
Here's a summary of the changes. To maintain backward compatibility, all parameters listed on API 4 still work on API 5. The source code is available on the 5.x branch, this will become the default branch in the future.
LuaJIT → C++
With API version 5 we've rewritten the entire codebase to C++ as a nginx module. The reason for this rewrite is to tighten the control over memory allocation. We found out that the current garbage collector (GC) in LuaJIT 2, which is essentially the same as the one in vanilla Lua 5.1, is not very fast for large workloads. A new GC is already proposed for LuaJIT 3.0, but it has not yet been implemented.
We also worried about the future of LuaJIT, given that the author of LuaJIT is stepping down. It is doubtful whether anyone will fill his shoes. The new C++ codebase ensures that we can continue our service for many years to come.
Revamped front-end
The old single index page had to be improved. We've completely revamped the front-end using VuePress, which allows us to write the documentation as regular Markdown files.
The documentation is available in our weserv/docs GitHub repository.
Improved rate limiter
We have improved our basic Redis rate limiter. Our new rate limiter is written in C and runs inside a Redis backed nginx module. The implementation is based on the onsigntv/redis-rate-limiter module, which offers a straightforward implementation of the fairly sophisticated generic cell rate algorithm, in 130 lines of C, without external dependencies.
An additional feature of this module is that it's easy to check your current rate limit quota:
$ curl -i https://wsrv.nl/quota
HTTP/1.1 200 OK
Date: Sun, 01 Sep 2019 00:00:00 GMT
X-RateLimit-Limit: 2500
X-RateLimit-Remaining: 2500
X-RateLimit-Reset: 0
{"X-RateLimit-Limit":2500, "X-RateLimit-Remaining":2500, "X-RateLimit-Reset":0}
TIP
Our limit is around 2500 images per 10 minutes. Accessing this endpoint does not count against your rate limit.
The source code of the rate limiter can be viewed on GitHub: weserv/rate-limit-nginx-module.
Support for animated images
Thanks to libvips 8.8, we've now enabled support for animated WebP and GIF images.
<img src="//wsrv.nl/?url=wsrv.nl/banana.webp&h=300&output=gif&n=-1">
![Animated image](https://wsrv.nl/?url=wsrv.nl/banana.webp&h=300&output=gif&n=-1)
Support for loading HEIC images
We've added support for loading HEIC-images. This is the new image compression standard being used by Apple and others. HEIC files are typically half the size of JPEG files at similar quality.
TIP
Saving to HEIC-images isn't supported due to patent issues. Hopefully the use of royalty-free encoding formats such as AVIF will become more widely used in the future.
CSS-inspired fit parameters
We've deprecated the confusing fit (&t=
) parameters (fit
, fitup
, square
, squaredown
, absolute
and letterbox
) and aligned it with the CSS terminology.
Here's a handy table to help users migrating to these new CSS-inspired parameters:
Before | After |
---|---|
&t=fit | &fit=inside&we |
&t=fitup | &fit=inside |
&t=square | &fit=cover |
&t=squaredown | &fit=cover&we |
&t=absolute | &fit=fill |
&t=letterbox | &fit=contain |
The new without enlargement parameter (&we
) can be used in combination with all &fit=
parameters. We also introduced a new parameter named &fit=outside
, which will resize an image to be as small as possible while ensuring its dimensions are greater than or equal to both those specified.
Tinting images
We introduced a new parameter named &tint
to tint an image using the provided chroma while preserving the image luminance.
<img src="//wsrv.nl/?url=wsrv.nl/lichtenstein.jpg&w=300&tint=red">
![Tint](https://wsrv.nl/?url=wsrv.nl/lichtenstein.jpg&w=300&tint=red)
Arbitrary rotation angles
Instead of only being able to rotate multiples of 90 degrees, any angle can now be given. The remaining space can be filled with a background color by using &rbg=
. To reflect this change, the &or=
parameter has been renamed to &ro=
.
<img src="//wsrv.nl/?url=wsrv.nl/lichtenstein.jpg&h=300&ro=45">
![Rotation](https://wsrv.nl/?url=wsrv.nl/lichtenstein.jpg&h=300&ro=45)
Adaptive filter and compression level
To minimize the size of PNG images and thus reduce their load time we've introduced some new parameters named &af
and &l
.
Metadata output
To quickly view the metadata of an image, we've added support for &output=json
. See here for an example.
Flip / flop an image
We've added support for flipping an image horizontally or vertically. You can combine these parameters to flip along both axes.
JSON for error messages
Instead of returning our error messages as plain text, you'll now receive a JSON-formatted response with the appropriate application/json
MIME-type. This makes it easier to integrate our service into any type of website or application.
Other improvements
- Improve Docker image and deployment (#180).
- A pre-resize crop behaviour (
&precrop
- #176). - Letterboxing without oversampling (
&fit=contain&we
- #173). - Retrieving the largest/smallest page from a multi-resolution image (
&page=-1
/&page=-2
- #170). - Defining the
max-age
of theCache-Control
HTTP-header (&maxage=31d
- #186). - Applying a duotone filter to an image (
&filt=duotone
). - Background color when using
&fit=contain
(&cbg=
). &a=crop-x%-y%
has been renamed to&a=focal-x%-y%
.&errorredirect=
has been renamed to&default=
.