本文将关心项目主页涉及的API。

相关的API包括:

我们以测试项目https://scratch.mit.edu/projects/277117877为例, 打开页面,加载的数据还真不少。

其中https://scratch.mit.edu/js/projects.bundle.js足有4.7M,下载时间就用了9.3s。

拉取项目数据

我们回到正题,开始关心各个API。既然是项目主页,首先得把整个项目的数据拉进页面,供用户浏览。我们便从这个说起。

项目数据包括项目的内部数据项目的外部数据(在Scratch3技术分析之创作平台API(第1篇)定义了这两个概念)

1
2
GET https://projects.scratch.mit.edu/277117877 # 项目的内部数据
GET https://api.scratch.mit.edu/projects/277117877 # 项目的外部数据

项目的内部数据

GET https://projects.scratch.mit.edu/277117877

1
{"targets":[{"isStage":true,"name":"Stage","variables":{"`jEk@4|i[#Fk?(8x)AV.-my variable":["我的变量",0]},"lists":{},"broadcasts":{},"blocks":{},"comments":{},"currentCostume":0,"costumes":[{"assetId":"cd21514d0531fdffb22204e0ec5ed84a","name":"背景1","md5ext":"cd21514d0531fdffb22204e0ec5ed84a.svg","dataFormat":"svg","rotationCenterX":240,"rotationCenterY":180}],"sounds":[{"assetId":"83a9787d4cb6f3b7632b4ddfebf74367","name":"啵","dataFormat":"wav","format":"","rate":44100,"sampleCount":1032,"md5ext":"83a9787d4cb6f3b7632b4ddfebf74367.wav"}],"volume":100,"layerOrder":0,"tempo":60,"videoTransparency":50,"videoState":"on","textToSpeechLanguage":null},{"isStage":false,"name":"角色1","variables":{},"lists":{},"broadcasts":{},"blocks":{"#ez$qP+47m]1?FAkK7EQ":{"opcode":"event_whenflagclicked","next":"4(Rs_W.WmWf$u^fquvr=","parent":null,"inputs":{},"fields":{},"shadow":false,"topLevel":true,"x":249,"y":-313},"4(Rs_W.WmWf$u^fquvr=":{"opcode":"motion_movesteps","next":"l]Zt{~YW17*uEI[V*-ru","parent":"#ez$qP+47m]1?FAkK7EQ","inputs":{"STEPS":[1,[4,"10"]]},"fields":{},"shadow":false,"topLevel":false},"l]Zt{~YW17*uEI[V*-ru":{"opcode":"microbit_displaySymbol","next":null,"parent":"4(Rs_W.WmWf$u^fquvr=","inputs":{"MATRIX":[1,"t2p#3HOI[w=AQ2`(S:@O"]},"fields":{},"shadow":false,"topLevel":false},"t2p#3HOI[w=AQ2`(S:@O":{"opcode":"matrix","next":null,"parent":"l]Zt{~YW17*uEI[V*-ru","inputs":{},"fields":{"MATRIX":["0101010101100010101000100"]},"shadow":true,"topLevel":false}},"comments":{},"currentCostume":0,"costumes":[{"assetId":"b7853f557e4426412e64bb3da6531a99","name":"造型1","bitmapResolution":1,"md5ext":"b7853f557e4426412e64bb3da6531a99.svg","dataFormat":"svg","rotationCenterX":48,"rotationCenterY":50},{"assetId":"e6ddc55a6ddd9cc9d84fe0b4c21e016f","name":"造型2","bitmapResolution":1,"md5ext":"e6ddc55a6ddd9cc9d84fe0b4c21e016f.svg","dataFormat":"svg","rotationCenterX":46,"rotationCenterY":53}],"sounds":[{"assetId":"83c36d806dc92327b9e7049a565c6bff","name":"喵","dataFormat":"wav","format":"","rate":44100,"sampleCount":37376,"md5ext":"83c36d806dc92327b9e7049a565c6bff.wav"}],"volume":100,"layerOrder":1,"visible":true,"x":0,"y":0,"size":100,"direction":90,"draggable":false,"rotationStyle":"all around"}],"monitors":[],"extensions":["microbit"],"meta":{"semver":"3.0.0","vm":"0.2.0-prerelease.20190102175344","agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"}}

为了获得好的阅读效果,你可以将它们复制到https://jsoneditoronline.org/

项目的外部数据

GET https://api.scratch.mit.edu/projects/277117877

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
{
  "id": 277117877,
  "title": "test-api",
  "description": "",
  "instructions": "操作说明",
  "visibility": "visible",
  "public": true,
  "comments_allowed": true,
  "is_published": true,
  "author": {
    "id": 40103875,
    "username": "api_test",
    "scratchteam": false,
    "history": { "joined": "1900-01-01T00:00:00.000Z" },
    "profile": {
      "id": null,
      "images": {
        "90x90": "https://cdn2.scratch.mit.edu/get_image/user/40103875_90x90.png?v=",
        "60x60": "https://cdn2.scratch.mit.edu/get_image/user/40103875_60x60.png?v=",
        "55x55": "https://cdn2.scratch.mit.edu/get_image/user/40103875_55x55.png?v=",
        "50x50": "https://cdn2.scratch.mit.edu/get_image/user/40103875_50x50.png?v=",
        "32x32": "https://cdn2.scratch.mit.edu/get_image/user/40103875_32x32.png?v="
      }
    }
  },
  "image": "https://cdn2.scratch.mit.edu/get_image/project/277117877_480x360.png",
  "images": {
    "282x218": "https://cdn2.scratch.mit.edu/get_image/project/277117877_282x218.png?v=1547524633",
    "216x163": "https://cdn2.scratch.mit.edu/get_image/project/277117877_216x163.png?v=1547524633",
    "200x200": "https://cdn2.scratch.mit.edu/get_image/project/277117877_200x200.png?v=1547524633",
    "144x108": "https://cdn2.scratch.mit.edu/get_image/project/277117877_144x108.png?v=1547524633",
    "135x102": "https://cdn2.scratch.mit.edu/get_image/project/277117877_135x102.png?v=1547524633",
    "100x80": "https://cdn2.scratch.mit.edu/get_image/project/277117877_100x80.png?v=1547524633"
  },
  "history": {
    "created": "2019-01-04T11:40:46.000Z",
    "modified": "2019-01-15T03:57:13.000Z",
    "shared": "2019-01-04T12:27:22.000Z"
  },
  "stats": {
    "views": 1,
    "loves": 0,
    "favorites": 0,
    "comments": 5,
    "remixes": 0
  },
  "remix": { "parent": null, "root": null }
}

每个字段的含义参考:Project Object

更新项目信息

更新项目名

PUT https://api.scratch.mit.edu/projects/277117877

以json形式提交了: {"title":"test-api2"}

服务器返回和GET https://api.scratch.mit.edu/projects/277117877一样的信息。

可以看出它们的url也是一样的

更新操作说明

PUT https://api.scratch.mit.edu/projects/277117877

以json形式提交了: {"instructions":"操作说明test"}

服务器返回同上。

更新备注与谢志

PUT https://api.scratch.mit.edu/projects/277117877

以json形式提交了: {"description":"test"}

服务器返回同上。

一致性非常好。

点赞(❤️/⭐️)

❤️代表loves, ⭐️代表favorites

这两个的接口十分相似:

1
2
POST https://api.scratch.mit.edu/proxy/projects/277117877/loves/user/api_test
POST https://api.scratch.mit.edu/proxy/projects/277117877/favorites/user/api_test

后端返回分别为

1
2
{"projectId":"277117877","userLove":true,"statusChanged":true} # ❤️
{"projectId":"277117877","userFavorite":true,"statusChanged":true}  # ⭐️

如果你要取消它们,API分别为

1
2
DELETE https://api.scratch.mit.edu/proxy/projects/277117877/loves/user/api_test # ❤️
DELETE https://api.scratch.mit.edu/proxy/projects/277117877/favorites/user/api_test # ⭐️

被改编/浏览的次数

被浏览的次数,一个用户最多贡献一次。可以使用redis的set来做(记录用户id)。

评论

最后我们来关心评论。这部分稍微复杂些。

顶层评论

POST https://api.scratch.mit.edu/proxy/comments/project/277117877

提交的json数据为: {"content":"test","parent_id":"","commentee_id":""}

注意到顶层评论的parent_id为空。

后端返回:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "id": 106196727,
  "parent_id": null,
  "commentee_id": null,
  "content": "test",
  "datetime_created": "2019-01-15T04:38:43.000Z",
  "datetime_modified": "2019-01-15T04:38:43.000Z",
  "visibility": "visible",
  "author": {
    "id": 40103875,
    "username": "api_test",
    "scratchteam": false,
    "image": "https://cdn2.scratch.mit.edu/get_image/user/40103875_60x60.png"
  },
  "reply_count": 0
}

子评论

POST https://api.scratch.mit.edu/proxy/comments/project/277117877

提交的json数据为: {"content":"子评论","parent_id":106196727,"commentee_id":40103875}

后端返回:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "id": 106196741,
  "parent_id": 106196727,
  "commentee_id": 40103875,
  "content": "子评论",
  "datetime_created": "2019-01-15T04:40:05.000Z",
  "datetime_modified": "2019-01-15T04:40:05.000Z",
  "visibility": "visible",
  "author": {
    "id": 40103875,
    "username": "api_test",
    "scratchteam": false,
    "image": "https://cdn2.scratch.mit.edu/get_image/user/40103875_60x60.png"
  },
  "reply_count": 0
}

对子评论的回复

POST https://api.scratch.mit.edu/proxy/comments/project/277117877

提交的json数据为: {"content":"对子评论 的回复","parent_id":106196727,"commentee_id":40103875}

后端返回:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "id": 106196774,
  "parent_id": 106196727,
  "commentee_id": 40103875,
  "content": "对子评论 的回复",
  "datetime_created": "2019-01-15T04:42:46.000Z",
  "datetime_modified": "2019-01-15T04:42:46.000Z",
  "visibility": "visible",
  "author": {
    "id": 40103875,
    "username": "api_test",
    "scratchteam": false,
    "image": "https://cdn2.scratch.mit.edu/get_image/user/40103875_60x60.png"
  },
  "reply_count": 0
}

可以看出parent_id始终指向顶级评论

关闭评论功能

PUT https://api.scratch.mit.edu/projects/277117877

提交的json数据为: {"comments_allowed":false}

删除评论

删除权利在项目拥有者手中,而不在评论发出者手中。

DELETE https://api.scratch.mit.edu/proxy/comments/project/277117877/comment/106196842

返回:{}

举报评论

POST https://api.scratch.mit.edu/proxy/project/277117877/comment/106196741/report

返回值: {"reportId":null}