# 【服务器深入探讨第 1 部分：命中 API】了解您的 Decentraland 场景如何连接到外部服务器并扩大您的创作可能性。

By [Decentraland 中文社区](https://paragraph.com/@decentraland-2) · 2022-03-29

---

![](https://storage.googleapis.com/papyrus_images/74e79743f6c7ce401456aa107f50ab6ee3381afd23bf08b3718f2fbe418d6740.png)

_2020-7-14文章_

本系列文章将专注于为您提供能够在场景中的玩家之间创建更丰富的共享体验的工具。 Decentraland 是一个社交空间，作为玩家，您可以做的许多最有价值的事情都要求您的行为对其他人可见并且是永久性的。

例如，在之前关于[创世纪广场](https://mirror.xyz/0x85A07dC63fF774b86eEdB62563d05D72bcbE8854/bRqMIEhRveoRXjVULl98MmwtAhcufKOAqPC0oxD72y8)的文章中，我们介绍了如何使用消息总线在同时处于场景中的玩家之间发送 P2P 消息。这是一个非常有用的工具，但它的局限性在于，玩家之间传递的任何信息都会在玩家离开场景后立即消失。 （如果一棵树倒在只使用消息总线的场景中并且周围没有人听到它，它会发出声音吗？）。如果您希望保留此对话以便稍后进入场景的其他玩家可以看到它怎么办？

我们将介绍此类问题和功能，以及您在此过程中会遇到的许多工具。我们感谢从开发的角度来看有更多经验丰富的观众，所以我们将以相对较慢的速度进行 - 在我们认为重要的地方解释概念。

关于 API
------

让我们从一个简单的任务开始：从 RESTful API 访问信息。

API 代表应用程序编程接口，REST 代表具象状态传输。 API 是应用程序通过代码与应用程序通信的一种方式，而 RESTful API 是通过遵循 REST 标准来实现的——但你现在真正需要了解的是 HTTP 用于发送信息。

您会惊讶于有多少网页和应用程序拥有自己的 API 来公开 Stuff As A Service，您只需向正确的地址发送 HTTP 请求即可访问这些 API。其中一些服务需要注册密钥，有些甚至需要付费，但其中很多都是免费开放的，只是在等待有人来玩。

查看 Programmable Web 以获取有关现有内容的精彩目录。例如，您可以调用一个问答 API，并免费将问答游戏的整个后端逻辑和内容放在盘子上。您还可以从 Twitter 获取图像以显示在您的场景中，显示来自帐户的最新消息或使用特定主题标签的最新消息。您还可以从 Binance 查询硬币价格、体育赛事的实时数据，以及大量其他可以让 Decentraland 了解“真实”世界事件的信息。

例如，在创世纪广场（东南角）的贸易中心大楼中，我们查询了许多 API 来显示来自加密市场的数据，包括 Binance API、OpenSea API 和我们自己的 Marketplace 中的 API。我们还查询我们的 Marketplace API 以从可穿戴设备大楼上出售的可穿戴设备中获取数据。我们还查询我们的事件 API 以显示当前在中央大楼附近的横幅上直播的任何事件。

现在是几点？
------

让我们看一个返回时间的简单 API。 Decentraland 场景无法访问您计算机的时钟，因为它在自己的沙箱环境中运行，但如果您调用 API，您仍然可以从互联网获取此信息。

这是一个简单的示例场景，它使用来自 API 的数据来告知时间并在特定时间开始派对：[github.com/decentraland-scenes/Party-Time](http://github.com/decentraland-scenes/Party-Time)

在这个场景中，我们使用 URL [https://worldtimeapi.org/api/timezone/etc/gmt+3](https://worldtimeapi.org/api/timezone/etc/gmt+3) 向 API 发送请求。由于这是一个简单的 GET 请求，没有标头或任何特殊内容，如果我们只是将 URL 粘贴到浏览器的另一个选项卡中，我们实际上可以看到我们从 API 返回的响应。如果您尝试这样做，您将得到与此类似的回应：

    {
      "abbreviation": "-03",
      "client_ip": "181.167.208.158",
      "datetime": "2020-06-03T16:34:28.699908-03:00",
      "day_of_week": 3,
      "day_of_year": 155,
      "dst": false,
      "dst_from": null,
      "dst_offset": 0,
      "dst_until": null,
      "raw_offset": -10800,
      "timezone": "Etc/GMT+3",
      "unixtime": 1591212868,
      "utc_datetime": "2020-06-03T19:34:28.699908+00:00",
      "utc_offset": "-03:00",
      "week_number": 23
    }
    

其它一些 API 需要具有更多花哨元素的请求，例如标头或正文，或者可能使用 POST 或 PUT 方法而不是 GET。发送和测试这些请求的一个很好的工具是 [Postman](https://www.postman.com/)。在开始编写代码作为场景的一部分之前，首先测试要发送的请求始终是一个好习惯。这样您就可以确定您将处理哪些输入和输出。

以下片段取自同一示例场景，浓缩了本文中最重要的内容。如果您有 Web 开发背景，那么您可能对这一切已经很熟悉了，但我们将为那些没有的人详细解释。如果您熟悉这些概念，请随意略过这部分。

    async function checkTime() {
      let url = 'https://worldtimeapi.org/api/timezone/etc/gmt+3'
      try {
        let response = await fetch(url)
        let json = await response.json()
        log(json)
      } catch {
        log('error getting time data')
      }
    }
    

Fetch
-----

_fetch()_ 函数是 JavaScript 和 TypeScript 中的常用函数，用于向 URL 发送 HTTP 请求。正如您在上面看到的，在其最简单的形式中，您只需向其传递一个 URL 并产生一个 GET 请求——就像您将 URL 写入 Web 浏览器一样。您还可以传递此方法的 HTTP 标头、HTTP 正文、不同的 HTTP 方法等。

在此处阅读有关 fetch 功能的更多信息：[developer.mozilla.org/en-US/docs/Web/API/Fetch\_API/Using\_Fetch](http://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)

解析 JSON
-------

大多数 API 将其响应作为 _.json_ 文件返回，该文件可能包含多个字段，其中包含您可能想要访问的数据。挑战在于，您真正收到的响应是包含所有这些信息的字符串，而您的场景不知道将其解释为字段和值的集合。如果您希望能够调用 JSON 结构中的各个值，您首先需要解析它，您可以通过在响应上运行 _.json()_ 函数轻松完成。

一旦我们从 API 获得解析的响应，我们就可以从响应 JSON 中访问不同的元素。例如我们可以得到 _json.datetime_ 或 _json.timezone_。如果对响应 JSON 的内容有疑问，请使用 Postman 发送模拟请求！

Try 和 Catch
-----------

此任务的执行依赖于某处服务器中远处发生的事情。由于我们无法控制它，因此最好始终将调用服务器的代码封装在 _Try_ 语句中。 _Catch_ 语句然后确定在 _Try_ 语句中的某些内容失败的情况下会发生什么。因此，如果我们调用的服务器出现故障，或者他们更改了端点——或者他们只是阻止我们的请求，因为他们出于某种原因对我们不利——我们的代码不会发生灾难性的失败。我们的场景只会耸耸肩，说“随便”，然后继续执行 _Catch_ 语句中的内容，毫不动摇。在上面的示例中，我们的 _Catch_ 语句只是记录一条消息，但它可以做我们需要它做的任何事情来保持节目运行。

Async 和 Await
-------------

如前所述，我们依赖于远程执行的东西，在这种情况下，我们还需要使用 _Async_ 和 _Await_ 语句。我们不知道我们的请求需要多长时间才能到达服务器，得到处理，然后返回给我们。我们不能在等待时让整个执行线程冻结。_Async_ 函数在其自己的线程上异步运行，它做自己的事情，并在场景的其余部分继续前进时花费尽可能多的时间。请注意，我们示例中定义的函数被标记为 _async_。 _Await_ 语句强制执行在移动到下一行代码之前等待响应。 _Await_ 语句只能在_async_ 代码块中使用，否则你会冻结主线程，这绝不是一个好主意。在上面的示例中，我们需要在 _fetch()_ 函数中添加一个 _await_，以便我们在处理它之前等待它的响应。如果没有第一次_await_，那么 _fetch()_ 函数将在其自己的单独线程中等待响应，同时我们会尝试在获得响应之前读取它的响应。 _response.json()_ 上的 _await_ 也是如此，因为消息的解析也是通常在其自己的线程中发生的事情，并且可能需要一些时间。否则我们会在解析之前尝试记录一些东西。

获取 Decentraland 活动
------------------

这是另一个简单的例子，取自你可以在 Genesis Plaza 找到的东西。该场景查看 Decentraland 活动 API 并显示当前在布告板上的所有活动，显示它们的标题、位置和图像。如果有多个现场活动，则布告板将循环通过它们。也可以单击板直接传送到活动的坐标。

[github.com/decentraland-scenes/Events-API](http://github.com/decentraland-scenes/Events-API)

**选择您常用的频道加入与我们联系，关注Decentraland(MANA)的最新动态**

**DCL基金会全球社区： 【**[**Official Website**](https://decentraland.org)】 【[**Telegram**](https://t.me/decentralandTG)】 【[**Blog**](https://blog.decentraland.org)】 【[**Twitter**](https://twitter.com/decentraland)】 【[**Discord**](https://decentraland.org/discord/)】

**DCL中文社区： 【**[**电报群**](https://t.me/+BtB90_SKDeQ4OGQ1)**】 【**[**推特**](https://twitter.com/decentralandcn)】 【[**微博**](https://weibo.com/decentralandcn)】 【**微信群**】请加微信ID ChinWaan 【**微信公众号**】manalandcn

---

*Originally published on [Decentraland 中文社区](https://paragraph.com/@decentraland-2/1-api-decentraland)*
