An excellent http framework that directly hits the pain point, allowing me to super efficiently complete the docking of third-party interfaces

1. Background

 

Because of the business relationship, it has to connect with many different third-party companies. These service providers provide http-based APIs. However, the specific details of the API provided by each company vary greatly.

 

Some are based on the RESTFUL specification, and some are based on the traditional http specification; some need to place a signature in the header, some need SSL two-way authentication, some only need SSL one-way authentication; some are serialized in JSON way, Some are serialized in XML. There are too many differences in details like this.

 

Different companies have different API specifications, which is normal. But for me, if I want the code to become elegant. I have to solve a pain point:

 

With so many differences in APIs of different service providers, how can we maintain a set of public http call suites that do not involve business? It is best to be distinguished by configuration or simple parameters. Make a convenient call?

 

Of course I know that there are many excellent and famous http open source frameworks that can implement any form of http calls, and I have used them in many years of development experience. For example, apache's httpClient package, very good Okhttp, jersey client.

 

The interface usage of these http open source frameworks is relatively different. No matter which one you choose, in my scenario, I don't want to write a bunch of http calling code when calling each third-party http api.

 

So, in this scenario, I have to encapsulate each different http api. Such code can be more elegant, and the coupling between business code and http call logic is lower.

 

Unfortunately, I am lazy. First, I think it takes more time to encapsulate, and second, I think there should be a better choice for encapsulating this underlying http call. I don't want to make wheels by myself.

 

So, I found an excellent open source http framework that can shield all the differences caused by different details of http api. It can complete extremely complex http calls through simple configuration like calling the rpc framework.

 

Forest

https://gitee.com/dt_flys/forest

 

 

 

2. Good

 

Forest supports Springboot's automatic assembly, so you only need to introduce a dependency

 

<dependency>
  <groupId>com.dtflys.forest</groupId>
  <artifactId>spring-boot-starter-forest</artifactId>
  <version>1.3.0</version>
</dependency>

 

Define your own interface class

 

public interface MyClient {

    @Request(url = "http://baidu.com")
    String simpleRequest();

    @Request(
            url = "http://ditu.amap.com/service/regeo",
            dataType = "json"
    )
    Map getLocation(@DataParam("longitude") String longitude, @DataParam("latitude") String latitude);  
}

 

Configure the scan package of the proxy interface class in the startup class

 

@SpringBootApplication
@ForestScan(basePackages = "com.example.demo.forest")
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

 

At this time, you can inject your proxy interface from the spring container and call the http api like calling a local method

 

@Autowired
private MyClient myClient;

@Override
public void yourMethod throws Exception {
    Map result = myClient.getLocation("124.730329","31.463683");
    System.out.println(JSON.toJSONString(result,true));
}

 

Log printing, Forest printed the http frame used internally, and the actual request url and return. Of course, the log can be configured to control the switch.

 

 

 

3. Features

 

I think this open source framework can help you improve a lot of efficiency, especially for those who are developing third-party APIs.

 

Two different http frameworks are encapsulated at the bottom of Forest: Apache httpClient and OKhttp. Therefore, this open source framework does not reinvent the wheels of the underlying implementation, but puts a lot of effort into ease of use.

 

I used Forest to finally complete the project to interface with multiple service provider APIs. For these APIs with different styles, I only took 1 hour to convert them into local methods. Then the project went online smoothly.

 

Forest is a higher-level http framework. In fact, you don't need to write a lot of code. Most of the time, you can complete http localized calls with only some configuration. The coverage of this framework is very wide, and it can satisfy most of your http call requests.

Forest has the following characteristics:

 

 

  • Take Httpclient and OkHttp as the backend framework

  • By calling local methods to send Http requests, the decoupling between business logic and Http protocol is realized

  • It is lighter than Feign and does not rely on Spring Cloud and any registry

  • Support all request methods: GET, HEAD, OPTIONS, TRACE, POST, DELETE, PUT, PATCH

  • Supports flexible template expressions

  • Support filters to filter the incoming data

  • Define Http request based on annotation and configuration

  • Support Spring and Springboot integration

  • Realize the serialization and deserialization of JSON and XML

  • Support JSON conversion framework: Fastjson, Jackson, Gson

  • Support JAXB form of XML conversion

  • Support SSL one-way and two-way encryption

  • Support the setting of http connection pool

  • The callback of the request result can be realized through the OnSuccess and OnError interface parameters

  • The configuration is simple, generally only a @Request annotation is required to complete the definition of most requests

  • Support asynchronous request call

 

 

 

4. Two great features

 

The usage and configuration methods are not described here. Those who are interested can read the detailed documents:

 

https://dt_flys.gitee.io/forest I just want to analyze 2 features of this framework that I think are better

 

4.1 Mapping and binding function of template expressions and parameters

 

Template expressions are particularly convenient when used, for example

 

@Request(
    url = "${0}/send?un=${1}&pw=${2}&ph=${3}&ct=${4}",
    type = "get",
    dataType = "json"
)
public Map send(
    String base,
    String userName,
    String password,
    String phone,
    String content
);

 

The above is to use the serial number subscript to get the value, and you can also get the value by name:

 

@Request(
    url = "${base}/send?un=${un}&pw=${pw}&ph=${3}&ct=${ct}",
    type = "get",
    dataType = "json"
)
public Map send(
    @DataVariable("base") String base,
    @DataVariable("un") String userName,
    @DataVariable("pw") String password,
    @DataVariable("ph") String phone,
    @DataVariable("ct") String content
);

 

It can even be simplified like this:

 

@Request(
    url = "${base}/send",
    type = "get",
    dataType = "json"
)
public Map send(
    @DataVariable("base") String base,
    @DataParam("un") String userName,
    @DataParam("pw") String password,
    @DataParam("ph") String phone,
    @DataParam("ct") String content
);

 

The above three writing methods are equivalent

 

Of course, you can also bind parameters to header and body. You can even use some expressions to simply serialize the object into json or xml:

 

@Request(
    url = "${base}/pay",
   contentType = "application/json",
    type = "post",
    dataType = "json",
    headers = {"Authorization: ${1}"},
    data = "${json($0)}"
)
public PayResponse pay(PayRequest request, String auth);

 

Of course, please refer to the documentation for details on data binding

 

4.2 Support for HTTPS

 

In the past, when using other http frameworks to handle https, I always found it particularly troublesome, especially for two-way certificates. Every time I encounter a problem, I can only go to baidu. Then modify your own code based on the experience of others.

 

Forest is also very thoughtful about this aspect. The bottom layer perfectly encapsulates the support for https one-way and two-way certificates. It can be completed quickly by simple configuration. Give a two-way certificate chestnut:

 

@Request(
    url = "${base}/pay",
   contentType = "application/json",
    type = "post",
    dataType = "json",
   keyStore = "pay-keystore",
   data = "${json($0)}"
)
public PayResponse pay(PayRequest request);

 

Where pay-keystore corresponds to ssl-key-stores in application.yml

 

forest:
  ...
  ssl-key-stores:
    - id: pay-keystore
      file: test.keystore
      keystore-pass: 123456
      cert-pass: 123456
      protocols: SSLv3

 

This setting is ok, and the rest is the call in the form of local code.

 

5. Finally

 

Forest has many other function settings. If you are interested, please read the documents and examples carefully.

 

But what I want to say is, I believe many people will definitely say that this is Feign after seeing this?

 

When I was developing the Spring Cloud project, I also used Feign for a while. Personally, I feel that Forest is indeed similar to Feign's design in configuration and usage, but Feign's role is more as a member of the Spring Cloud ecosystem. As the role of RPC communication, it is not only responsible for http communication, but also load balancing the call address issued by the registry.

 

The Forest, an open source project, is positioned as a high-end http tool, focusing on friendliness and ease of use. From the perspective of use, I personally feel that Forest configuration is simpler and more direct. Many functions provided can also solve the pain points of many people.

 

The spirit of open source is commendable, and good open source requires everyone's contribution and support. I hope this article can bring you a new choice when choosing http client framework: Forest

Guess you like

Origin blog.csdn.net/jcmj123456/article/details/108438660