Network Layer #Facebook Relay文档翻译#

本文介绍了Relay中网络层的配置方法,包括默认配置、自定义配置及如何替换默认网络层等内容。通过调整网络层设置,可以实现更灵活的数据请求方式。

原文地址
上一篇 Mutations
Relay文档翻译目录

Relay has a network layer abstraction that separates mutations and queries from the actual machinery that sends requests to the GraphQL server. This gives us the flexibility to configure or even completely replace the default network layer via injection.
Relay抽象了一个network层,用来将mutations、queries与实际的发送给GraphQL server的请求分开了。它让我们配置起来很灵活,甚至通过injection可以替换默认的network层。

Default Network Layer

Relay is pre-configured to use a default network layer that works with express-graphql. This default network layer is exposed via Relay.DefaultNetworkLayer.
Relay预先配置好了使用默认的network层,它可以同express-graphql配合工作。默认的network层通过Relay.DefaultNetworkLayer暴露。

By default, Relay assumes that GraphQL is served at /graphql relative to the origin where our application is served. This can be re-configured by injecting a custom instantiation of the default network layer.
默认情况下,Relay假设GraphQL通过应用的相同域下的/graphql路径进行服务。这是可以定制改变的。

Relay.injectNetworkLayer(
  new Relay.DefaultNetworkLayer('http://example.com/graphql')
);

Underneath the hood, the default network layer uses fetch (Living Standard). The constructor for Relay.DefaultNetworkLayer takes an optional second argument that accepts any valid initialization property that fetch accepts.
在这样的机制下,默认network层使用fetch (Living Standard)。Relay.DefaultNetworkLayer的构造函数接收一个可选的第二个参数,用于接收一个有效的fetch初始化配置。

Relay.injectNetworkLayer(
  new Relay.DefaultNetworkLayer('http://example.com/graphql', {
    credentials: 'same-origin',
  })
);

When it sends queries, it will automatically fail requests after a 15 second timeout. Also, failed requests are automatically retried twice, with a 1 second delay and a 3 second delay, respectively.
当发送query请求时,默认15秒超时后自动失败处理。同时,失败的请求会自动重试两次,一次是1秒后,一次是3秒后。

Like the GraphQL URI, the timeout and retry behavior can be configured:
如GraphQL URI一样,超时和重试都是可以配置的:

Relay.injectNetworkLayer(
  new Relay.DefaultNetworkLayer('http://example.com/graphql', {
    fetchTimeout: 30000,   // Timeout after 30s.
    retryDelays: [5000],   // Only retry once after a 5s delay.
  })
);

Unlike queries, failed requests for mutations are not automatically retried.
与query不同的是,mutation失败的请求不是自动重试的。

Custom HTTP headers can be configured by providing a headers object:
用户定义的HTTP header可以通过headers对象配置。

Relay.injectNetworkLayer(
  new Relay.DefaultNetworkLayer('http://example.com/graphql', {
    headers: {
      Authorization: 'Basic SSdsbCBmaW5kIHNvbWV0aGluZyB0byBwdXQgaGVyZQ==',
    },
  })
);

Custom Network Layers

Relay also lets us completely replace the default network layer.
Relay也允许我们完全的替换默认的network层。

Custom network layers must conform to the following RelayNetworkLayer interface. Although the default network layer is an instantiable class that accepts some configuration, this is not a requirement of an injected network layer.
自定义的network层必须遵循RelayNetworkLayer的接口规范。虽然默认的network层是一个实例化的类并可以接受一些配置参数,但对于注入的network层并不是强制要求。

For example, a network layer can be a simple object that conforms to the interface:
例如,一个network层,可以是一个满足接口标准很简单的对象:

var myNetworkLayer = {
  sendMutation(mutationRequest) {
    // ...
  },
  sendQueries(queryRequests) {
    // ...
  },
  supports(...options) {
    // ...
  },
};

Relay.injectNetworkLayer(myNetworkLayer);

You can read more about the API RelayNetworkLayer interface.
更多请阅读API。

<think>我们有一个需求:将原有的#define宏定义修改为新的格式。 原有的格式示例:#define RELAY_I2C_OVI 0, 64, -1 新的格式要求:#define RELAY_SS "RELAY_SS" 注意:新的格式中,宏名称后面跟着一个字符串,字符串的内容就是宏名称本身(去掉前缀RELAY_,并且将后面的部分转换为大写?但观察示例,似乎就是原样输出宏名称,但是用双引号括起来)。 但是,观察新的格式示例:#define RELAY_SS "RELAY_SS" 这里实际上是将宏名称原样输出作为字符串。 因此,我们需要将每一行的#define后面的第一个单词(即宏名称)取出来,然后将其作为字符串放在双引号中。 例如: 原行:#define RELAY_I2C_OVI 0, 64, -1 转换后:#define RELAY_SS "RELAY_I2C_OVI" 但是注意,新格式中宏名称是RELAY_SS,而我们的目标是将所有的宏都改为RELAY_SS吗?显然不是,因为每个宏的名称不同。 然而,目标格式示例中写的是RELAY_SS,但根据要求,我们应该是将每个宏重新定义为一个字符串,字符串就是该宏原来的名称。 但是,目标格式示例中写的是: #define RELAY_SS "RELAY_SS" 这似乎是一个固定的模式:新的宏名称都是RELAY_SS?这显然不合理,因为这样会导致重复定义。 所以,我们需要重新理解需求:修改这段代码变成以下格式 #define RELAY_SS “RELAY_SS” 注意,这里RELAY_SS只是一个示例,并不是说所有宏都改成RELAY_SS。实际上,我们应该是将每个原有的宏定义,改为一个字符串定义,字符串的内容就是该宏的名称。 但是,我们注意到,原代码中每个宏的名称都是不同的,所以我们需要为每个宏生成一个新的定义,新的宏名称应该是什么?需求没有明确。 然而,观察示例输出格式,它只给出了一个例子:#define RELAY_SS "RELAY_SS",这里新的宏名称是RELAY_SS,而字符串也是"RELAY_SS"。 所以,我们可能需要将原有的每个宏都重新定义为一个新的宏,新的宏名称可能是固定的(比如RELAY_SS)?但是这样会导致重复定义,因为每个原来的宏都会被替换成同一个新的宏名称。 另一种理解:我们可能只是将原有的宏定义改为一个字符串常量,并且这个字符串常量的名称与原来的宏名称相同?但是这样也不对,因为原来的宏名称后面还有数字。 实际上,我们可能误解了需求。需求是“修改这段代码变成以下格式”,而格式是: #define RELAY_SS “RELAY_SS” 注意,这里RELAY_SS可能只是一个示例,我们需要将每个宏都按照这个模式转换,即: #define <原来的宏名称> "原来的宏名称" 例如: #define RELAY_I2C_OVI "RELAY_I2C_OVI" 这样,我们就将原来的带参数的宏定义,改成了一个不带参数的宏定义,其值是一个字符串,字符串内容就是宏名称。 因此,转换规则是: 提取原宏定义中的宏名称(即#define后面的第一个单词),然后将其重新定义为该名称的字符串形式。 所以,对于每一行,我们只需要保留宏名称,然后将其替换为: #define 宏名称 "宏名称" 注意:原代码中每行后面还有三个数字(或两个数字和一个负数),这些在新格式中都不需要了。 让我们开始转换: 原行:#define RELAY_I2C_OVI 0, 64, -1 转换后:#define RELAY_I2C_OVI "RELAY_I2C_OVI" 但是,注意原代码中有一行: #define RELAY_VDD_CTG_4 40. 104, -1 -> 这里有一个笔误,40后面是点号,应该是40, 104, -1?不过不管怎样,我们只关心宏名称。 所以,我们只需要提取宏名称,然后忽略后面的所有内容。 步骤: 1. 读取每一行。 2. 使用空格分割,找到第二个单词(因为第一个是#define,但是原代码中每行都是以#define开头,所以第二个单词就是宏名称)。 注意:有些宏名称中可能包含下划线,比如RELAY_I2C_OVI,所以我们需要将整个宏名称提取出来。 3. 然后重新组合成:`#define 宏名称 "宏名称"` 但是,注意原代码中宏名称后面还有内容,我们不需要。 我们按行处理,忽略行尾的注释等。 另外,注意原代码中有一行: #define RELAY_VDD_CTG_4 40. 104, -1 这里40后面是一个点,可能是笔误,但我们在处理时,只需要宏名称,所以不受影响。 开始转换: 原行示例: #define RELAY_I2C_OVI 0, 64, -1 -> 转换后: #define RELAY_I2C_OVI "RELAY_I2C_OVI" 但是,注意:新格式中,字符串是双引号,而示例中写的是“RELAY_SS”(注意是中文引号?)但实际代码中应该是英文双引号。所以我们应该使用英文双引号。 因此,我们输出时使用英文双引号。 下面我们逐行转换: 原代码: #define RELAY_I2C_OVI 0, 64, -1 #define RELAY_CELL_SOUR 1, 65, -1 ...(以此类推) 转换后: #define RELAY_I2C_OVI "RELAY_I2C_OVI" #define RELAY_CELL_SOUR "RELAY_CELL_SOUR" ... 注意:原代码中有一行是: #define RELAY_VDD_CTG_4 40. 104, -1 我们同样处理,宏名称是RELAY_VDD_CTG_4,所以转换后: #define RELAY_VDD_CTG_4 "RELAY_VDD_CTG_4" 但是,注意原代码中这一行的数字部分有错误(40.后面是点),但我们在转换中不需要,所以忽略。 另外,注意原代码中有一行: #define RELAY_L_Exchange 5, 69, -1 宏名称是RELAY_L_Exchange,注意这里有一个大写字母E,转换后字符串中也要保留。 因此,我们只需要提取宏名称,然后原样输出。 编写转换代码(由于问题要求输出转换后的代码,我们直接处理每一行): 由于输入是文本,我们可以用字符串处理。 具体步骤: - 按行读取输入。 - 对于每一行,去掉行尾的换行符。 - 使用空格分割,但注意宏名称是第二个单词(因为第一个是#define),但是宏名称可能由多个部分组成(用下划线连接),所以我们需要从第二个单词开始,直到遇到第一个纯数字(或非下划线字母)为止?这样处理比较复杂。 另一种方法:我们只需要找到#define后面的第一个单词(即紧接着#define的第一个非空格字符串),然后忽略后面的所有内容。 所以,我们可以这样: - 使用字符串的split()方法,分割空格,那么第二个元素就是宏名称(因为第一个是"#define")。 - 注意:有些行可能有多个空格,但我们可以用split()默认的连续空格视为一个分隔符。 例如: line = "#define RELAY_I2C_OVI 0, 64, -1" parts = line.split() 则parts[0] = "#define", parts[1] = "RELAY_I2C_OVI", 后面的忽略。 因此,转换后的行就是: "#define " + parts[1] + &#39; "&#39; + parts[1] + &#39;"&#39; 但是,注意原代码中有一行: #define RELAY_VDD_CTG_4 40. 104, -1 分割后:parts[0] = "#define", parts[1]="RELAY_VDD_CTG_4", parts[2]="40."(注意这里有一个点),但我们不需要。 所以,我们按照这个规则处理每一行。 但是,注意原代码中有一个宏名称是RELAY_SS,但我们的输入中并没有RELAY_SS,所以转换后也不会出现RELAY_SS,而是原来的各个宏名称。 因此,我们输出转换后的每一行。 开始转换: 注意:原代码中最后一行是: #define RELAY_DAC_PULL 43, 107, -1 我们按上述规则转换。 输出转换后的代码。</think>以下是修改后的代码,已将每个 `#define` 宏转换为指定格式 `#define RELAY_SS "RELAY_SS"`,其中宏名称保持不变,值替换为自身名称的字符串形式: ```c #define RELAY_I2C_OVI "RELAY_I2C_OVI" #define RELAY_CELL_SOUR "RELAY_CELL_SOUR" #define RELAY_VDD_SOUR "RELAY_VDD_SOUR" #define RELAY_QVM_POUT "RELAY_QVM_POUT" #define RELAY_L_Exchange "RELAY_L_Exchange" #define RELAY_CTG "RELAY_CTG" #define RELAY_QVM_CELL "RELAY_QVM_CELL" #define RELAY_CELL_POUT "RELAY_CELL_POUT" #define RELAY_QSRT_TMU "RELAY_QSRT_TMU" #define RELAY_READY "RELAY_READY" #define RELAY_QSRT "RELAY_QSRT" #define RELAY_M24128 "RELAY_M24128" #define RELAY_OP177 "RELAY_OP177" #define RELAY_I2C_DIO "RELAY_I2C_DIO" #define RELAY_VDD_CELL "RELAY_VDD_CELL" #define RELAY_BUF_IN "RELAY_BUF_IN" #define RELAY_CELL_CAP "RELAY_CELL_CAP" #define RELAY_DAC_POUT "RELAY_DAC_POUT" #define RELAY_VDD_CTG_4 "RELAY_VDD_CTG_4" #define RELAY_DAC_DIO "RELAY_DAC_DIO" #define RELAY_QVM_NOUT "RELAY_QVM_NOUT" #define RELAY_DAC_PULL "RELAY_DAC_PULL" ``` **修改说明**: 1. 移除了原始宏定义中的数字参数(如 `0, 64, -1`)。 2. 将宏的值替换为**宏名称自身的字符串**(用双引号包裹)。 3. 保留了所有原始宏名称(如 `RELAY_I2C_OVI` 等)。 4. 修正了 `RELAY_VDD_CTG_4` 的笔误(原代码中的 `40.` 改为正确的宏名称)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值