如何在Youtube v3 Data API中使用Etags?

时间:2016-04-11 19:28:26

标签: javascript caching etag youtube-data-api

我正在构建一个扩展程序,它会产生很多的请求。我正在处理的功能是显示观看播放列表所需的总时间。给定大小为1000的播放列表,我必须发出40个请求才能找到这些信息(50个视频在一个时间限制内,第一次调用/ v3 / playlistItems用于一系列videoID,第二次调用/ v3 / videos持续时间信息)。据我所知,只有一个播放列表,我失去600个配额。每页加载。我知道,没有什么可以解决的,因为我每天允许50,000,000配额,但我想尽早优化。这也是一个速度问题。只需要一段时间就可以获得播放列表的长度。

现在,ETags。出于某种原因,每当我向youtube的视频或播放列表项目数据API发出请求时,我都会得到一个全新的Etag(大多数情况下,我有过返回相同ETag的情况),无论播放列表如何(我还没有尝试私人播放列表,但还没有尝试过OAuth。我假设原因是播放列表中的某些地方正在发生变化,导致新的Etag非常快。看法? PlaylistItems甚至不返回视图!

以下是通心粉播放列表的示例API调用。 ETag总是与众不同!如果他们不工作,我该如何使用它们?它们是特定的,视频长度无法在请求之间发生变化。 api键被省略,因为你可以创建自己的api密钥。

```
Playlist Items, give me video id's, page tokens, and Etag for playlist for items 100-150
https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails&maxResults=50&playlistId=PLF-hTvh6KCehzImlI2pAKsOFPR62QZTv-&fields=etag%2Citems%2FcontentDetails%2CnextPageToken%2CprevPageToken&key={YOUR_API_KEY}&pageToken=CGQQAA

Videos, give me durations and Etag for these video ids
https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id=SswxpqGX1F0,3Hy5BuFTBbI,ZnlW1fSXZZM,8sb_YOrReZ4,6IN_mupBjh8,VzoqsRLY5Qk,5m8H9YrPvPA,JdRbtGdR68E,hEzPBiYPsDU,bJuioKFYv-c,1N8O8OOG2_U,QDgqSL8nU5U,gP4gB45Z52M,pI1oB2y9c0M,WZGn5Vh_mc4,A0KpbS5WjSU,b0yoIOX8Bk0,5Y7iQt7vtOE,qIijCwjUApQ,RgHjqvznjxg,QzceROWtn5o,8z0VnMQFGR8,5olHoTWB1Hw,vz0T59Ql7fQ,LhktiZYQraU,WIuuZOD9ahI,rwEHW6GRH1Q,FjT1BpKvfgo,FRZL2yaZyZk,U5-vjCDwDUU,b21Lj9bfDWc,yox3-U7r_i8,rXJ5ph83Vrs,nXrk2finMcA,VfagTkQWHuI,K_ZaRAtZQOg,_JIcREsn9pU,y9WGvudeDAM,O08jNtrieI4,9UkEzW1AY7Y,jOaBdnYsobg,y7dSbhc-8h0,IfpPiCGcF8g,2rTRmb9nKbY,bHgv3A26O6Y,hFQmV-zvcbM,Osc4y45oQxw,GHusS6Yd5A8,T2Z3CuUWUQc,OPV-DopMqxs&fields=etag%2Citems%2FcontentDetails%2Fduration&key={YOUR_API_KEY}
```

我想缓存这些数据。我正在考虑为播放列表的总视频提出额外的开始请求,因为这与播放列表的总时间长度直接相关。但这感觉就像很多逻辑。添加/删除了哪些视频?多少?如果它被添加到开头,我想要进行优化,我必须将前50个视频ID与我的缓存视频ID持续时间进行比较。如果它在中间某处改变了,我必须继续查询。也许缓存别的东西让这更容易?多个播放列表可以拥有相同的视频,播放列表可以不止一次拥有相同的视频,我不知道。也许没有办法查询整个播放列表,也许我应该将调用缓存到/ v3 / videos。问题是我想优化对/ v3 / playlistItems的调用,因为它是长的(对/ v3 /视频的时间是3倍)。

我的主要问题是:我如何缓存以优化获取播放列表的长度,我该如何做以及使用ETag做什么?

4 个答案:

答案 0 :(得分:3)

我想出了如何暂时缓存数据,抱歉!

您可以拨打/播放列表来获取播放列表中的项目总数,以及etag更改当且仅当播放列表本身发生更改时,这就是我想要的。我只想在基本播放列表发生变化时发出新请求。

对/ playlistItems的调用始终会生成新的etag,无论更改如何。我认为这个端点用于临时查询,以确定与播放列表相关的视频元数据,而不是静态数据查找。播放列表非常灵活,我认为YouTube决定不缓存此数据,因为对/ playlistItems的调用通常是逐个案例的。它们的后端可能会自动生成etag,但实际上并没有为此端点保存任何内容。

因此,这些是获取播放列表的总时间长度以及缓存的步骤:

  1. 获取播放列表ID
  2. 按播放列表ID
  3. 在缓存中查找etag
  4. 使用If-None-Match标题中的etag调用/播放列表(即使etag为空也应该有效)
    • 如果api返回304,则使用缓存的播放列表长度
    • 如果api返回200,则将新etag保存在缓存中
    • 你可以做更多的缓存!
  5. 带有播放列表ID的call / playlistItems(包含所有pageTokens)
  6. 在缓存中查找每个videoId以获取视频长度
    • 缓存定义为videoId:videoLength
    • 的字典
    • 如果找不到videoLength,请将videoId添加到videos数组
    • 如果找到videoLength,请添加到lengths数组
  7. 在缓存中找不到最多50个元素的所有视频ID的来电/视频
    • 可以在/ playlistItems调用之后立即完成,或者当所有调用完成后,我认为现在可以保持懒惰并在每次调用后立即执行
    • 此外,您可以使用etags缓存视频通话并保存以检查长度是否未更改,但是您必须为每个视频调用api。我不知道,但我认为这是过度优化。仍然可能需要记住,调试时,视频长度可以通过YouTube的编辑工具进行更改
  8. (从7开始)对于响应中的每个视频,将视频长度作为videoId:videoLength对缓存在字典中,然后将长度添加到lengths数组
  9. lengths数组缩减为moment.js持续时间对象
  10. 保存播放列表长度的格式化字符串,以etag为键缓存
  11. 返回播放列表长度的格式化字符串
  12. Here is the implementation on my github

答案 1 :(得分:1)

eTag不会更改每个请求。但是,您可以针对特定请求获得特定数量的不同eTag。 原因是响应中的一些元素改变了它们的顺序,因此创建eTag的算法产生不同的eTag。只要两个响应的内容元素的顺序完全相同,eTag就会再次相同。我记录了一堆请求,并得出了这个结论。通过id和part = brandingSettings,snippet测试通道请求。 如果在响应中选择多个具有嵌套元素的部分,您将获得更多不同的组合,从而获得不同的eTag。

答案 2 :(得分:0)

当您运行相同的查询且内容未发生变化时,YouTube Data API会返回一个始终在变化的Etag。因此,看起来就像Etag实现一样。

但事实上,事实并非如此。如果您在请求中提供之前收到的Etag,则YouTube Data API将正常运行。它将识别Etag,并将以HTTP状态304 Not Modified回答。

答案 3 :(得分:0)

我发现,只有当你使用“part = id”并且不使用“maxResults = NN”时,etag才能正常工作。 否则,每次调用API都会返回新的etag。