Home > Back-end >  How to update a resource view count in REST API?
How to update a resource view count in REST API?

Time:03-02

I have an application containing videos. Each of the videos has a view count (represented by a property total_views) along with other properties such as its title, uploader, etc. A video view count should be incremented by 1 every time a video is requested/watched. The frontend of this application is a Next.js SPA and the backend is a Lumen/Laravel REST API.

The current REST API backend solution returns the total_views as part of the video entity when the GET /videos/{id} endpoint is called on the API.

I am not sure how to implement video count updates in the most REST generally accepted convention compliant way. I thought of updating the count on a request to GET /videos/{id} but I believe that this is not common REST standards/specification compliant (causing issues with caching, etc.) since the total_views property of the entity object in the response is being updated too. The second option I thought of is using another endpoint such as POST/PUT/PATCH /videos/{id}/views. However, I do not want to use a request body as the backend API should always increment by 1 only (and this way avoiding the client tampering with the view count). Another drawback of this option is that it introduces extra overhead as it requires sending another HTTP request in addition to the GET request for getting the video info.

What are your suggestions?

EDIT: Video view count here might also be seen as page view counts instead of actual video views/plays (Video resource views). Accurate view counting that filters out page views of crawlers, bots, or views where the visitor did not start the video are outside the scope of this question.

The videos are hosted by external 3-rd party hosts and are only embedded via embed codes (iframe) in this application's video web pages.

CodePudding user response:

To do what you want correctly, you really want an 'increment' operation. This operation does not need a previous count, send the new total.

The best fitting HTTP method is indeed PATCH. PATCH can do many things, and it's up to you to decide the meaning. For example, if your PATCH request looks like this, it's 100% correct:

PATCH /videos/{id}/views
Content-Type: application/vnd.your-company-name.increment
Content-Length: 0

You can also invent a little JSON format:

PATCH /videos/{id}/views
Content-Type: application/vnd.your-company-name.increment json

{
  "action": "increment"
}

The first format does not use a body at all, which is what you asked for.. but since your goal with the empty body was to prevent tampering with the number, it's not actually required to use an empty body.

It might be less confusing to users that only ever use JSON with APIs that you have an endpoint without a body, so the second example is a very little JSON document that just tell the server to increment the view count.

You don't strictly have to use a custom mimetype. Its a good idea, but if you don't want to you use can also use application/octet-stream and application/json for these two requests respectively.

A better plan

I do believe its actually better the GET request to the video itself, instead of having the tracking done as a side-effect via javascript.

Given that you mention that you're on PHP, you could for example do this using the XSendFile module (if you're on nginx, other servers probably have an equivalent):

https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/

The general steps are:

  1. Intercept the GET request to the actual video with PHP
  2. Count the view
  3. Using XSendFile, send the file over (so you don't keep an active PHP process for the duration of sending the video).

If the file is hosted entirely something else, like S3, there might also be ways to tap into the server access log and count GET requests there.

  • Related