Skip to content

Commit

Permalink
add docs about traffic-split
Browse files Browse the repository at this point in the history
  • Loading branch information
LCDZhao-Z committed Apr 22, 2022
1 parent 2e4db6b commit 34b84ce
Show file tree
Hide file tree
Showing 20 changed files with 956 additions and 1 deletion.
5 changes: 4 additions & 1 deletion site/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,11 @@ enable = false

# multi-versions
[[params.versions]]
version = "v1.0.1 (Latest)"
version = "v1.0.2 (Latest)"
url = "/docs"
[[params.versions]]
version = "v1.0.1"
url = "/docs-v1.0.1"
[[params.versions]]
version = "v0.1.0"
url = "/docs-v0.1.0"
19 changes: 19 additions & 0 deletions site/content/en/docs-v1.0.1/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: "ESA RestClient"
linkTitle: "ESA RestClient"
weight: 10
description: >
ESA RestClient is an asynchronous event-driven http client based on netty.
---
## Features
- Http1/H2/H2cUpgrade
- Https
- Epoll/NIO
- Serialize and Deserialize
- Interceptor
- Filter
- Retry, Redirect, 100-expect-continue
- Segmented read/write
- Multipart
- Metrics
- more features...
8 changes: 8 additions & 0 deletions site/content/en/docs-v1.0.1/codec/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
tags: ["extension"]
title: "Codec"
linkTitle: "Codec"
weight: 20
description: >
用户请求时`RestClient`会自动根据用户的 `Headers` 与 `Entity` 自动选择合适的`Decoder`或`Encoder`进行`Decode`或`Encode`。同时`RestClient`也支持用户在`codec`前后进行插入业务逻辑。
---
199 changes: 199 additions & 0 deletions site/content/en/docs-v1.0.1/codec/decoder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
---
tags: ["extension"]
title: "Decoder"
linkTitle: "Decoder"
weight: 20
description: >
`RestClient`会自动根据用户的 `Headers` 与 期望`Entity`类型 等选择合适的`Decoder`进行解码。`RestClient`内置了下面这些`Decoder`:
- Json
- jackson :默认,自动通过SPI的方式注入到RestClient中
- fastjson :需要引入`fastjson`依赖,并将`FastJsonCodec`添加到RestClient中
- gson :需要引入`gson`依赖,并将`GsonCodec`添加到RestClient中
- ProtoBuf :需要引入`ProtoBuf`依赖,并将`ProtoBufCodec`添加到RestClient中
- String :自动通过SPI的方式注入到RestClient中
- byte[] :自动通过SPI的方式注入到RestClient中
除此之外`RestClient`也支持用户自定义解码器。
---
## 使用Json Decoder
当Response的`contentType``MediaType.APPLICATION_JSON`,将自动使用`Json Decoder`来来进行`Decode`
```java
final RestClient client = RestClient.ofDefault();
RestResponseBase response = client.get("localhost:8080/aaa")
.execute()
.toCompletableFuture()
.get();

//当 response.contentType() == MediaType.APPLICATION_JSON 时将自动使用Json Decoder
Person person = response.bodyToEntity(Person.class);

```
{{< alert title="Note" >}}
其中Json相关的序列化方式默认配置了日期格式为`yyyy-MM-dd HH:mm:ss`
{{< /alert >}}
## 使用ProtoBuf Decoder
### Step1 : 引入ProtoBuf依赖
```xml
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>
```
### Step2 : 使用 ProtoBuf Decoder 进行解码
将ProtoBufCodec加入到RestClient中, 当Response的`contentType``ProtoBufCodec.PROTO_BUF`,且`response.bodyToEntity()`传入的类型为`com.google.protobuf.Message`的子类时,将自动使用`ProtoBuf Decoder`来进行`Decode`
```java
//将ProtoBufCodec加入到RestClient中
final RestClient client = RestClient.create()
.addDecoder(new ProtoBufCodec())
.build();

RestResponseBase response = client.get("localhost:8080/aaa")
.execute()
.toCompletableFuture()
.get();

//当 ProtoBufCodec.PROTO_BUF.isCompatibleWith(response.contentType()),且 Person 为 Message 的子类时,将自动使用ProtoBuf Decoder
Person person = response.bodyToEntity(Person.class);

```
## 使用String Encoder
`response.bodyToEntity()`传入的类型为`String.class`,且Response的`contentType`不为`MediaType.APPLICATION_JSON`时,将自动使用`String Decoder`来进行`Decode`
```java
final RestClient client = RestClient.ofDefault();
RestResponseBase response = client.get("localhost:8080/aaa")
.execute()
.toCompletableFuture()
.get();

//当 !MediaType.APPLICATION_JSON.isCompatibleWith(response.contentType()) 时,自动使用String Decoder来进行Decode
String result = response.bodyToEntity(String.class);

```
## 使用byte[] Encoder
`response.bodyToEntity()`传入的类型为`byte[].class`,且Response的`contentType`不为`MediaType.APPLICATION_JSON`时,将自动使用`byte[] Decoder`来进行`Decode`
```java
final RestClient client = RestClient.ofDefault();
RestResponseBase response = client.get("localhost:8080/aaa")
.execute()
.toCompletableFuture()
.get();

//当 !MediaType.APPLICATION_JSON.isCompatibleWith(response.contentType()) 时,自动使用byte[] Decoder来进行Decode
byte[] result = response.bodyToEntity(byte[].class);
```

## 自定义Decoder
`RestClient`内置的`Decoder`无法满足用户需求时,用户可以自定义`Decoder`,示例如下:
```java
public class StringDecoder implements ByteDecoder {

@Override
public Object doDecode(DecodeContext<byte[]> ctx) {
if (String.class.isAssignableFrom(ctx.targetType())) {
return new String(ctx.content().value());
}
return ctx.next();
}
}
```
{{< alert title="Tip" >}}
`RestClient`中,同时存在多个`Decoder`,它们之间通过`getOrder()`方法返回值区分执行顺序,值越小,优先级越高。
针对当前`Decoder`,分为两种情况:
- 当前`Decoder`可以`Decode`该响应:
直接返回`Decode`后的结果。
- 当前`Decoder`不可以`Decode`该响应:
调用`ctx.next()`,将`Decode`工作交给下一个`Decoder`,如果`RestClient`中的所有`Decoder`都无法编码该请求,则`RestClient`将抛出`CodecException`异常。
{{</alert>}}
### 配置Decoder
#### Builder
在构造`RestClient`时传入自定义的`Decoder`实例,如:
```java
final RestClient client = RestClient.create()
.addDecoder(ctx -> {
//decode...
return ctx.next();
})
.build();
```
#### SPI
##### 普通SPI
`RestClient`支持通过SPI的方式加载`Decoder`接口的实现类,使用时只需要按照SPI的加载规则将自定义的`Decoder`放入指定的目录下即可。
##### DecoderFactory
如果用户自定义的`Decoder`对于不同`RestClient`的配置有不同的实现,则用户可以实现`DecoderFactory`接口,并按照SPI的加载规则将自定义的`DecoderFactory`放入指定的目录下即可。
```java
public interface DecoderFactory {
Collection<Decoder> decoders(RestClientOptions clientOptions);
}
```
`RestClient`构建时将调用`DecoderFactory.decoders(RestClientOptions clientOptions)`,该方法返回的所有`Decoder`都将加入到构建好的`RestClient`中。
#### 直接绑定Request
`Decoder`可以直接绑定`Request`,使用方式如下:
```java
final RestResponseBase response = client.post(url)
.entity(new File("aaa"))
.decoder(ctx -> {
//decode...
return ctx.next();
})
.execute()
.toCompletableFuture()
.get();
```
{{< alert title="Tip" >}}
`Request`绑定了`Decoder`,该Client中设置的所有`Decoder`将对该请求失效。即:如果当前`Decoder`无法解码该响应,则`RestClient`将会抛出CodecException异常。
{{< /alert >}}

### 执行时机
[请求处理完整流程](../process_of_restclient/)中的`Decoder`

## DecodeAdvice
用户可以通过`DecodeAdvice``Decode`前后进行来插入业务逻辑,来对要解码的 `ResponseContent` 或者 `Decode`后的对象 进行修改替换等操作。
### 示例
```java
public class DecodeAdviceImpl implements DecodeAdvice {
@Override
public Object aroundDecode(DecodeAdviceContext ctx) throws Exception {
//...before decode
Object decoded = ctx.next();
//...after decode
return decoded;
}
}
```
{{< alert title="Tip" >}}
多个`DecodeAdvice`之间通过`getOrder()`方法返回值区分执行顺序,值越小,优先级越高。
{{< /alert >}}
### 配置方式
#### Builder
在构造`RestClient`时传入自定义的`DecodeAdvice`实例,如:
```java
final RestClient client = RestClient.create()
.addDecodeAdvice(ctx ->{
//...before decode
Object decoded = ctx.next();
//...after decode
return decoded;
})
.build();
```

#### SPI
##### 普通SPI
`RestClient`支持通过SPI的方式加载`DecodeAdvice`接口的实现类,使用时只需要按照SPI的加载规则将自定义的`DecodeAdvice`放入指定的目录下即可。
##### DecodeAdviceFactory
如果用户自定义的`DecodeAdvice`对于不同`RestClient`的配置有不同的实现,则用户可以实现`DecodeAdviceFactory`接口,并按照SPI的加载规则将自定义的`DecodeAdviceFactory`放入指定的目录下即可。
```java
public interface DecodeAdviceFactory {
Collection<DecodeAdvice> decodeAdvices(RestClientOptions clientOptions);
}
```
`RestClient`构建时将调用`DecodeAdviceFactory.decodeAdvices(RestClientOptions clientOptions)`,该方法返回的所有`DecodeAdvice`都将加入到构建好的`RestClient`中。

### 执行时机
[请求处理完整流程](../process_of_restclient/)中的`DecodeAdvice`

0 comments on commit 34b84ce

Please sign in to comment.