Triple Rest User Manual

Triple Rest User Manual

This article is the user manual for Triple Rest

Note

Starting from Dubbo version 3.3, the original Rest protocol has been moved to the Extensions library, with the Triple protocol providing more comprehensive support for Rest. If you need to continue using the original Rest protocol, you can introduce the corresponding dubbo-spi-extensions library dependency.

Introduction

Since the Dubbo version 3.3, the Triple protocol reuses the existing HTTP protocol stack, achieving comprehensive REST-style service export capabilities. Users can decentralize directly to access backend Triple protocol services via HTTP protocol without using generic or gateway layer protocol conversion or configuration. Additionally, rich annotations and SPI extension support is provided for advanced REST usage, such as path customization, output format customization, and exception handling. Key features include:

  • Triple Protocol Integration
    Reuses the existing Triple HTTP protocol stack, requiring no additional configuration or new ports to simultaneously support HTTP/1, HTTP/2, and HTTP/3 protocols.

  • Decentralization
    Allows direct exposure of REST APIs without relying on gateway applications for traffic forwarding, thereby improving performance and reducing stability risks caused by gateways. Security issues can be resolved through internal application extensions, a practice already validated within Taobao’s MTOP.

  • Support for Existing Servlet Facilities
    Supports Servlet API and Filters, allowing users to reuse existing security components based on the Servlet API. Integration with security frameworks like OAuth and Spring Security can be easily achieved by implementing a Servlet Filter.

  • Multiple Dialects
    Considering that most users are accustomed to using SpringMVC or JAX-RS for REST API development, Triple Rest allows for continued use of these methods to define services and supports most of the extensions and exception handling mechanisms (providing more than 80% of the functionality of the original framework). For users pursuing a lightweight solution, the Basic dialect can be used. The out-of-the-box REST access capability of Triple is based on this dialect for service exposure.

  • Strong Extensibility
    Provides more than 20 extension points, enabling users to not only easily create custom dialects but also flexibly customize parameter retrieval, type conversion, error handling, and other logic.

  • Out-of-the-Box
    REST capabilities are available out-of-the-box; by simply enabling the Triple protocol, you gain direct REST service access capabilities.

  • High-Performance Routing
    Uses an optimized Radix Tree and Zero Copy technology to enhance routing performance.

  • Seamless OpenAPI Integration (TBD)
    OpenAPI integration is nearing completion, providing support for exporting OpenAPI Schemas out-of-the-box. By introducing the Swagger dependency, you can use a web UI for service testing. With OpenAPI Schema, tools like Postman and Apifox can be used to manage and test APIs, enabling easy cross-language calls through the OpenAPI ecosystem. In the future, further support for the Schema-First approach will be implemented, allowing teams to first define OpenAPI together with frontend teams. The frontend can generate calling code and mocks based on OpenAPI, while the backend uses OpenAPI to generate stubs for service development, greatly improving collaboration efficiency.

Quick Start

Let’s start with a simple example to understand Triple Rest. You can directly download existing sample projects to get started quickly, assuming you have Java, Maven, and Git installed.

Download and Run Sample

## Get sample code
git clone --depth=1 https://github.com/apache/dubbo-samples.git
cd dubbo-samples/2-advanced/dubbo-samples-triple-rest/dubbo-samples-triple-rest-basic
## Run directly
mvn spring-boot:run
## Or package and run
mvn clean package -DskipTests
java -jar target/dubbo-samples-triple-rest-basic-1.0.0-SNAPSHOT.jar

Of course, you can also import the project directly using an IDE and execute org.apache.dubbo.rest.demo.BasicRestApplication#main to run.

Sample Code

// Service Interface
package org.apache.dubbo.rest.demo;

import org.apache.dubbo.remoting.http12.rest.Mapping;
import org.apache.dubbo.remoting.http12.rest.Param;

public interface DemoService {
    String hello(String name);

    @Mapping(path = "/hi", method = HttpMethods.POST)
    String hello(User user, @Param(value = "c", type = ParamType.Header) int count);
}

// Service Implementation
@DubboService
public class DemoServiceImpl implements DemoService {
    @Override
    public String hello(String name) {
        return "Hello " + name;
    }

    @Override
    public String hello(User user, int count) {
        return "Hello " + user.getTitle() + ". " + user.getName() + ", " + count;
    }
}

// Model
@Data
public class User {
    private String title;
    private String name;
}

Test Basic Service

curl -v "http://127.0.0.1:8081/org.apache.dubbo.rest.demo.DemoService/hello?name=world"
## Output as follows
#> GET /org.apache.dubbo.rest.demo.DemoService/hello?name=world HTTP/1.1
#> Host: 127.0.0.1:8081
#> User-Agent: curl/8.7.1
#> Accept: */*
#>
#* Request completely sent off
#< HTTP/1.1 200 OK
#< content-type: application/json
#< alt-svc: h2=":8081"
#< content-length: 13
#<
#"Hello world"

Code Explanation:
You can see the output “Hello world”. The double quotes are due to the default output content-type being application/json.
This example demonstrates that Triple by default exports services to /{serviceInterface}/{methodName} and supports passing parameters via URL.

Test Advanced Service

curl -v -H "c: 3" -d 'name=Yang' "http://127.0.0.1:8081/org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr"
## Output as follows
#> POST /org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr HTTP/1.1
#> Host: 127.0.0.1:8081
#> User-Agent: curl/8.7.1
#> Accept: */*
#> c: 3
#> Content-Length: 9
#> Content-Type: application/x-www-form-urlencoded
#>
#* upload completely sent off: 9 bytes
#< HTTP/1.1 200 OK
#< content-type: text/plain
#< alt-svc: h2=":8081"
#< content-length: 17
#<
#Hello Mr. Yang, 3

Code Explanation:
You can see the output Hello Mr. Yang, 3. The absence of double quotes is because the output is specified as text/plain due to the use of the .txt suffix.
This example illustrates how to customize paths using the Mapping annotation, which allows for the customization of parameter sources, and supports passing parameters through post body or URL. For detailed explanations, see: Basic Usage Guide.

Log Observation

You can enable debug logging to understand the startup and response request process of REST.

logging:
  level:
    "org.apache.dubbo.rpc.protocol.tri": debug
    "org.apache.dubbo.remoting": debug

Once enabled, you can observe the Rest mapping registration and request response process.

## Register mapping
DEBUG o.a.d.r.p.t.TripleProtocol               :  [DUBBO] Register triple grpc mapping: 'org.apache.dubbo.rest.demo.DemoService' -> invoker[tri://192.168.2.216:8081/org.apache.dubbo.rest.demo.DemoService]
 INFO .r.p.t.r.m.DefaultRequestMappingRegistry :  [DUBBO] BasicRequestMappingResolver resolving rest mappings for ServiceMeta{interface=org.apache.dubbo.rest.demo.DemoService, service=DemoServiceImpl@2a8f6e6} at url [tri://192.168.2.216:8081/org.apache.dubbo.rest.demo.DemoService]
DEBUG .r.p.t.r.m.DefaultRequestMappingRegistry :  [DUBBO] Register rest mapping: '/org.apache.dubbo.rest.demo.DemoService/hi' -> mapping=RequestMapping{name='DemoServiceImpl#hello', path=PathCondition{paths=[org.apache.dubbo.rest.demo.DemoService/hi]}, methods=MethodsCondition{methods=[POST]}}, method=MethodMeta{method=org.apache.dubbo.rest.demo.DemoService.hello(User, int), service=DemoServiceImpl@2a8f6e6}
DEBUG .r.p.t.r.m.DefaultRequestMappingRegistry :  [DUBBO] Register rest mapping: '/org.apache.dubbo.rest.demo.DemoService/hello' -> mapping=RequestMapping{name='DemoServiceImpl#hello~S', path=PathCondition{paths=[org.apache.dubbo.rest.demo.DemoService/hello]}}, method=MethodMeta{method=org.apache.dubbo.rest.demo.DemoService.hello(String), service=DemoServiceImpl@2a8f6e6}
 INFO .r.p.t.r.m.DefaultRequestMappingRegistry :  [DUBBO] Registered 2 REST mappings for service [DemoServiceImpl@44627686] at url [tri://192.168.2.216:8081/org.apache.dubbo.rest.demo.DemoService] in 11ms

## Request Response
DEBUG .a.d.r.p.t.r.m.RestRequestHandlerMapping :  [DUBBO] Received http request: DefaultHttpRequest{method='POST', uri='/org.apache.dubbo.rest.demo.DemoService/hi.txt?title=Mr', contentType='application/x-www-form-urlencoded'}
DEBUG .r.p.t.r.m.DefaultRequestMappingRegistry :  [DUBBO] Matched rest mapping=RequestMapping{name='DemoServiceImpl#hello', path=PathCondition{paths=[/org.apache.dubbo.rest.demo.DemoService/hi]}, methods=MethodsCondition{methods=[POST]}}, method=MethodMeta{method=org.apache.dubbo.rest.demo.DemoService.hello(User, int), service=DemoServiceImpl@2a8f6e6}
DEBUG .a.d.r.p.t.r.m.RestRequestHandlerMapping :  [DUBBO] Content-type negotiate result: request='application/x-www-form-urlencoded', response='text/plain'
DEBUG .d.r.h.AbstractServerHttpChannelObserver :  [DUBBO] Http response body is: '"Hello Mr. Yang, 3"'
DEBUG .d.r.h.AbstractServerHttpChannelObserver :  [DUBBO] Http response headers sent: {:status=[200], content-type=[text/plain], alt-svc=[h2=":8081"], content-length=[17]}

General Functionality

Path Mapping

Compatible with SpringMVC and JAX-RS mapping methods. Relevant documentation:

It also supports custom path mapping through the SPI org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMappingResolver.

Supported Patterns

  1. books: String constant, the most basic type, matches a fixed segment.
  2. ?: Matches a single character.
  3. *: Matches zero or more characters in a path segment.
  4. **: Matches zero or more path segments until the end of the path.
  5. {spring}: Matches a path segment and captures it as a variable named “spring”.
  6. {spring:[a-z]+}: Matches a path segment using the regex [a-z]+ and captures it as a path variable named “spring”.
  7. {*spring}: Matches zero or more path segments until the end, capturing them as a variable named “spring”; if written as {*}, it indicates no capture.

Examples (from Spring documentation)

  • /pages/t?st.html — Matches /pages/test.html and /pages/tXst.html, but not /pages/toast.html.
  • /resources/*.png — Matches all .png files in the resources directory.
  • com/**/test.jsp — Matches all test.jsp files under the com path.
  • org/springframework/**/*.jsp — Matches all .jsp files under the org/springframework path.
  • /resources/** — Matches all files under the /resources/ path, including /resources/image.png and /resources/css/spring.css.
  • /resources/{*path} — Matches all files under /resources/ and captures their relative paths in a variable named “path”.
  • /resources/{filename:\\w+}.dat — Matches /resources/spring.dat and assigns “spring” to the filename variable.
  • /{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+} — Matches /example-2.1.5.html where name is example, version is 2.1.5, and ext is .html.

A little tip: if you use regex and want to avoid crossing segments, you can use {name:[^/]+} to match.

Complete Process of Mapping Matching

The specific matching processing code: DefaultRequestMappingRegistry.java RequestMapping.java

  1. Use PathUtils.normalize to clean the path, removing indirect paths such as /one/../ and ensuring it starts with /.
  2. Check if the http method matches.
  3. Check if the path matches.
  4. Check if the parameter matches (JAX-RS does not support this).
  5. Check if the header matches.
  6. Check if the content-type matches (Consumes).
  7. Check if the accept matches (Produces).
  8. Check if the serviceGroup and serviceVersion match.
  9. Check if the method initial signature matches.
  10. If no matches were found and tailing / matching is enabled, try removing the tailing / to see if it matches from step 2.
  11. If no matches were found, and suffix matching is enabled and supported, try removing the suffix to see if it matches from step 2.
  12. If the last path segment contains ~, indicating initial method signature matching is enabled, try matching from step 2.
  13. If there are zero candidates, the matching ends and returns null.
  14. If there are candidates, the matching ends and returns the hit item.
  15. If more than one candidate, sort the candidates.
  16. Perform sequential comparison between the first and second items.
  17. A result of 0 indicates the final match cannot be confirmed, throwing an exception.
  18. If the first item wins, match ends and return the hit item.

Path Duplication Issue

Unlike Spring, which reports errors and prevents startup when paths are identical, Triple Rest has out-of-the-box characteristics. To avoid affecting existing services, by default it only logs WARN messages. At runtime, if it cannot ultimately determine the highest priority mapping, it throws an error.

Parameter Types

Different dialects support different parameter types; details can be found in various dialect user guides.
It also supports custom parameter parsing by implementing the SPI org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentResolver.

General Type Parameters

Name Description Basic Annotation SpringMVC Annotation JAX-RS Annotation Array/Collection Handling Map Handling
Param Query or Form parameter @Param @RequestParam - Multi-value All params as Map
Query URL parameters - - @QueryParam Multi-value All Query params as Map
Form Form parameters - - @FormParam Multi-value All Form params as Map
Header HTTP header @Param(type=Header) @RequestHeader @HeaderParam Multi-value All Header params as Map
Cookie Cookie values @Param(type=Cookie) @CookieValue @CookieParam Multi-value All Cookie params as Map
Attribute Request attribute @Param(type=Attribute) @RequestAttribute - Multi-value All Attributes as Map
Part Multipart file @Param(type=Part) @RequestHeader @HeaderParam Multi-value All Parts as Map
Body Request body @Param(type=Body) @RequestBody @Body Attempt to parse as array or collection Attempt to parse to target type
PathVariable Path variable @Param(type=PathVariable) @PathVariable @PathParam Single-value array or collection Single-value Map
MatrixVariable Matrix variable @Param(type=MatrixVariable) @MatrixVariable @MatrixParam Multi-value Single-value Map
Bean Java bean No annotation @ModelAttribute @BeanParam Attempt to parse as Bean array or collection -

Special Type Parameters

Type Description Activation Condition
org.apache.dubbo.remoting.http12.HttpRequest HttpRequest object Default activated
org.apache.dubbo.remoting.http12.HttpResponse HttpResponse object Default activated
org.apache.dubbo.remoting.http12.HttpMethods Request Http method Default activated
java.util.Locale Request Locale Default activated
java.io.InputStream Request Input stream Default activated
java.io.OutputStream Response Output stream Default activated
javax.servlet.http.HttpServletRequest Servlet HttpRequest object Include Servlet API jar
javax.servlet.http.HttpServletResponse Servlet HttpResponse object Same as above
javax.servlet.http.HttpSession Servlet HttpSession object Same as above
javax.servlet.http.Cookie Servlet Cookie object Same as above
java.io.Reader Servlet Request Reader object Same as above
java.io.Writer Servlet Response Writer object Same as above

Parameters Without Annotations

Different dialects handle this differently; please refer to each dialect’s user instructions.

Accessing HTTP Input and Output Parameters Without Parameters

You can access them via RpcContext.

// Dubbo http req/resp
HttpRequest request = RpcContext.getServiceContext().getRequest(HttpRequest.class);
HttpResponse response = RpcContext.getServiceContext().getRequest(HttpResponse.class);
// Servlet http req/resp
HttpServletRequest request = RpcContext.getServiceContext().getRequest(HttpServletRequest.class);
HttpServletResponse response = RpcContext.getServiceContext().getRequest(HttpServletResponse.class);

After obtaining the request, you can access some built-in attributes through attributes; see: RestConstants.java.

Parameter Type Conversion

By default, most parameter type conversions from String to target type are supported, including the following major categories:

  • Java built-in types, including primitive types and dates, Optionals, etc.
  • Array types
  • Collection types
  • Map types

It fully supports generic types, including complex nesting. For specific implementation code, see: GeneralTypeConverter.java.
It also supports custom parameter type conversion by implementing the SPI org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentConverter.

Source Type Target Type Description Default Value
String double Converts to a double 0.0d
String float Converts to a float 0.0f
String long Converts to a long 0L
String int Converts to an integer 0
String short Converts to a short 0
String char Converts to a character 0
String byte Converts to a byte 0
String boolean Converts to a boolean false
String BigInteger Converts to a BigInteger null
String BigDecimal Converts to a BigDecimal null
String Date Converts to a Date null
String Calendar Converts to a Calendar null
String Timestamp Converts to a Timestamp null
String Instant Converts to an Instant null
String ZonedDateTime Converts to a ZonedDateTime null
String LocalDate Converts to a LocalDate null
String LocalTime Converts to a LocalTime null
String LocalDateTime Converts to a LocalDateTime null
String ZoneId Converts to a ZoneId null
String TimeZone Converts to a TimeZone null
String File Converts to a File null
String Path Converts to a Path null
String Charset Converts to a Charset null
String InetAddress Converts to an InetAddress null
String URI Converts to a URI null
String URL Converts to a URL null
String UUID Converts to a UUID null
String Locale Converts to a Locale null
String Currency Converts to a Currency null
String Pattern Converts to a Pattern null
String Class Converts to a Class null
String byte[] Converts to a byte array null
String char[] Converts to a char array null
String OptionalInt Converts to an OptionalInt null
String OptionalLong Converts to an OptionalLong null
String OptionalDouble Converts to an OptionalDouble null
String Enum class Enum.valueOf null
String Array or Collection Split by comma null
String Specified class Try JSON String to Object null
String Specified class Try construct with single String null
String Specified class Try call static method valueOf null

Supported Content-Type

By default, the following Content-Type is supported, providing corresponding encoding and decoding functionality.
It also supports extending by implementing the SPI org.apache.dubbo.remoting.http12.message.(HttpMessageDecoderFactory|HttpMessageEncoderFactory).

Media Type Description
application/json JSON format
application/xml XML format
application/yaml YAML format
application/octet-stream Binary data
application/grpc gRPC format
application/grpc+proto gRPC with Protocol Buffers
application/x-www-form-urlencoded URL-encoded form data
multipart/form-data Form data with file upload
text/json JSON format as text
text/xml XML format as text
text/yaml YAML format as text
text/css CSS format
text/javascript JavaScript format as text
text/html HTML format
text/plain Plain text

Content Negotiation

Supports a complete content negotiation mechanism, which can negotiate the output Content-Type based on mappings or input, with the following process:

  1. Try to read mediaType specified by the Mapping, obtaining the list of mediaTypes specified by Produces, and wildcard matching to suitable Media Type. For example, Spring’s: @RequestMapping(produces = "application/json").
  2. Try to find mediaType through the Accept header, parsing the incoming Accept header and wildcard matching to suitable Media Type. For example: Accept: application/json.
  3. Try to find mediaType through format parameter, reading format parameter values to match suitable Media Type as file suffix. For example /hello?format=yml.
  4. Try to find mediaType through the extension of the request path, matching the suffix as a file extension suitable Media Type. For example /hello.txt.
  5. Try to read the Content-Type header of the request as Media Type (excluding form types). For example Content-Type: application/json.
  6. Use application/json as fallback.

CORS Support

Provides complete CORS support, which can be enabled by configuring global parameters; the default behavior is consistent with SpringMVC. Additionally, in SpringMVC dialects, there is support for fine-tuned configuration through @CrossOrigin.
Supported CORS configuration items can be referred to: 8.4 CORS Configuration.

Custom HTTP Output

Many scenarios require custom HTTP output, such as performing 302 redirects or writing HTTP headers. For this, Triple Rest provides the following generic solutions and also supports specific methods in various dialects. Please refer to the respective dialect user guides.

  • Set the return value to: org.apache.dubbo.remoting.http12.HttpResult; you can build via HttpResult#builder.
  • Throw Payload exception: throw new org.apache.dubbo.remoting.http12.exception.HttpResultPayloadException(HttpResult) Example code:
throw new HttpResult.found("https://a.com").toPayload();

This exception avoids filling erroneous stack traces, has little impact on performance, and does not require considering return value logic; this method is recommended for customizing output.

  • Obtain HttpResponse and customize, example code:
HttpResponse response = RpcContext.getServiceContext().getRequest(HttpResponse.class);

response.sendRedirect("https://a.com");
response.setStatus(404);
response.outputStream().write(data);
// It is recommended to call commit after writing to avoid being overridden by other extensions
response.commit();

If only adding http header, this method is recommended.

Custom JSON Parsing and Output

Supports various JSON frameworks such as Jackson, fastjson2, fastjson, and gson etc.; please ensure that the corresponding jar dependencies are included before use.

Specify the JSON Framework to Use

dubbo.protocol.triple.rest.json-framework=jackson

Customize using JsonUtil SPI

You can customize JSON handling by implementing the SPI org.apache.dubbo.common.json.JsonUtil; specific implementations can be referenced from org/apache/dubbo/common/json/impl. It is recommended to inherit existing implementations and override them.

Exception Handling

Unhandled exceptions are ultimately converted into the encoded ErrorResponse class and output:

@Data
public class ErrorResponse {
    /**
     * http status code
     */
    private String status;

    /**
     * exception message
     */
    private String message;
}

Note: For errors 500 and above, to avoid leaking internal server information, only the message “Internal Server Error” will be output by default. If you need to customize the message, create a custom exception inheriting from org.apache.dubbo.remoting.http12.exception.HttpStatusException and override the getDisplayMessage method.
The following utilities are provided for customizing exception handling:

  • Refer to 9.2 Custom Exception Return Results for using SPI to customize global exception handling.
  • Use Dubbo’s Filter SPI to process and convert exceptions; if access to the Http context is needed, inherit org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilterAdapter.
  • Use the SPI org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilter to convert exceptions; this is lightweight and provides path-matching capabilities.

Note: The last two methods can only intercept exceptions occurring in the invoke chain; if an exception occurs during the path-matching stage, only method 1 can handle it.

Basic Usage Guide

See examples: dubbo-samples-triple-rest/dubbo-samples-triple-rest-basic.

Path Mapping

Basic, as an out-of-the-box REST mapping, will default to map methods to: /{contextPath}/{serviceInterface}/{methodName}. If /{contextPath} is not configured, it will be ignored, thus resulting in: /{serviceInterface}/{methodName}.
Custom mapping is supported through the annotation org.apache.dubbo.remoting.http12.rest.Mapping, with the following property descriptions:

Configuration Name Description Default Behavior
value Mapped URL path, can be one or more paths. Empty array
path Mapped URL path, same as value, can be one or more paths. Empty array
method List of supported HTTP methods, e.g. GET, POST, etc. Empty array (supports all methods)
params List of parameters that must be included in the request. Empty array
headers List of headers that must be included in the request. Empty array
consumes Content types (Content-Type) for processing requests, can be one or more types. Empty array
produces Content types (Content-Type) generated for responses, can be one or more types. Empty array
enabled Whether to enable this mapping. true (enabled)
  • Properties support configuration using placeholders: @Mapping("${prefix}/hi").
  • If you do not want a specific service or method to be exported as REST, you can set @Mapping(enabled = false) to resolve the issue.

Parameter Types

General parameters can be referred to in: 3.2 Parameter Types.

Parameters Without Annotations

Basic’s unannotated parameters are supported by the class: FallbackArgumentResolver.java and the detailed processing flow is as follows:
rest-arg.jpg .

SpringMVC Usage Guide

See examples: dubbo-samples-triple-rest/dubbo-samples-triple-rest-springmvc.

Path Mapping

Directly refer to SpringMVC documentation, supporting most features: Mapping Requests :: Spring Framework.
Note that there is no need for @Controller or @RestController annotations; in addition to @RequestMapping, a new @HttpExchange is also supported.

Parameter Types

General Parameters

See: 3.2 Parameter Types.

Annotated Type Parameters

Refer to 3.2.1 General Type Parameters.

Special Type Parameters

Type Description Activation Condition
org.springframework.web.context.request.WebRequest WebRequest object Include SpringWeb dependency
org.springframework.web.context.request.NativeWebRequest NativeWebRequest object Same as above
org.springframework.http.HttpEntity HTTP entity Same as above
org.springframework.http.HttpHeaders HTTP headers Same as above
org.springframework.util.MultiValueMap Multi-value map Same as above

Parameters Without Annotations

Parameter Type Conversion

Prioritize using Spring’s org.springframework.core.convert.ConversionService to convert parameters; if the application is a Spring Boot application, mvcConversionService will be used by default; otherwise, obtain the shared ConversionService through org.springframework.core.convert.support.DefaultConversionService#getSharedInstance.
If ConversionService does not support it, it will fall back to general type conversion: 3.3 Parameter Type Conversion.

Exception Handling

In addition to supporting the methods mentioned in 3.8 Exception Handling, it also supports the Spring @ExceptionHandler annotation method: Exceptions :: Spring Framework. Note that using this method can only handle exceptions thrown during method calls; other exceptions cannot be caught.

CORS Configuration

In addition to supporting global configuration for 8.4 CORS Configuration, it also supports Spring @CrossOrigin for fine-tuning configuration: CORS :: Spring Framework.

Custom HTTP Output

Supports the following Spring customization methods:

  1. Use @ResponseStatus annotation.
  2. Return org.springframework.http.ResponseEntity object.

Supported Extensibility

JAX-RS Usage Guide

See examples: dubbo-samples-triple-rest/dubbo-samples-triple-rest-jaxrs.

Path Mapping

The service needs to explicitly add the @Path annotation, and methods need to add request method annotations like @GET, @POST, @HEAD, etc.
Directly refer to the Resteasy documentation, supporting most features: Chapter 4. Using @Path and @GET, @POST, etc.

Parameter Types

General Parameters

See: 3.2 Parameter Types.

Annotated Type Parameters

Annotation Parameter Location Description
@QueryParam querystring Corresponding parameters to ?a=a&b=b
@HeaderParam header
@PathParam path
@FormParam form Body in the format key1=value2&key2=value2
Without annotation body Not explicitly using an annotation

Special Type Parameters

Type Description Activation Condition
javax.ws.rs.core.Cookie Cookie object Include Jax-rs dependencies
javax.ws.rs.core.Form Form object Same as above
javax.ws.rs.core.HttpHeaders HTTP Headers Same as above
javax.ws.rs.core.MediaType Media type Same as above
javax.ws.rs.core.MultivaluedMap Multi-value map Same as above
javax.ws.rs.core.UriInfo URI information Same as above

Parameters Without Annotations

  • For basic types (determined by TypeUtils#isSimpleProperty), get them directly from the Parameter.
  • For non-basic types, treat them as request body (body) to decode into an object.

Parameter Type Conversion

You can extend to customize parameter conversion using the extension interface:

org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentResolver
javax.ws.rs.ext.ParamConverterProvider

Exception Handling

You can extend to customize exception handling using the extension interface:

javax.ws.rs.ext.ExceptionMapper
org.apache.dubbo.remoting.http12.ExceptionHandler

CORS Configuration

Supports global configuration for 8.4 CORS Configuration.

Custom HTTP Output

Supports the following JAX-RS customization methods:

  • Return javax.ws.rs.core.Response object.

Supported Extensions

  1. javax.ws.rs.container.ContainerRequestFilter
    Request filters that allow preprocessing requests before they reach resource methods.
  2. javax.ws.rs.container.ContainerResponseFilter
    Response filters that allow post-processing of responses after they leave resource methods.
  3. javax.ws.rs.ext.ExceptionMapper
    Exception mappers that map thrown exceptions to HTTP responses.
  4. javax.ws.rs.ext.ParamConverterProvider
    Parameter converters that allow converting request parameters to resource method parameter types.
  5. javax.ws.rs.ext.ReaderInterceptor
    Read interceptors that allow interception and processing when reading request entities.
  6. javax.ws.rs.ext.WriterInterceptor
    Write interceptors that allow interception and processing when writing response entities.

Servlet Usage Guide

Supports both low-version javax and high-version jakarta servlet APIs, with priority given to jakarta APIs. Just include the JAR to use HttpServletRequest and HttpServletResponse as parameters.

Using Filter Extensions

Method 1: Implement the Filter interface and org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtension interface, then register SPI.

import org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtension;

import javax.servlet.Filter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class DemoFilter implements Filter, RestExtension {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        chain.doFilter(request, response);
    }

    @Override
    public String[] getPatterns() {
        return new String[]{"/demo/**", "!/demo/one"};
    }

    @Override
    public int getPriority() {
        return -200;
    }
}

Method 2: Implement the Supplier<Filter> interface and org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtension interface, then register SPI.

public class DemoFilter implements Supplier<Filter>, RestExtension {

    private final Filter filter = new SsoFilter();

    @Override
    public Filter get() {
        return filter;
    }
}

This method is very convenient for reusing existing filters and allows obtaining Filter instances from Spring Context and registering.

public class DemoFilter implements Supplier<Filter>, RestExtension {

    private final Filter filter = new SsoFilter();

    public DemoFilter(FrameworkModel frameworkModel) {
        SpringExtensionInjector injector = SpringExtensionInjector.get(frameworkModel.defaultApplication());
        filter = injector.getInstance(SsoFilter.class, null);
    }

    @Override
    public Filter get() {
        return filter;
    }
}

HttpSession Support

Implement SPI org.apache.dubbo.rpc.protocol.tri.rest.support.servlet.HttpSessionFactory.

Features Not Yet Supported

  • The request and response objects wrapped in the filter will not function because there are many types of filters supported by REST, and using wrappers can lead to nested handling complexities.
  • The request.getRequestDispatcher is not supported.

Security Configuration

When REST services are exposed directly to the public, there is a security risk of being attacked. Therefore, before exposing services, it is necessary to evaluate risks thoroughly and choose appropriate authentication methods to ensure security. Triple provides various security authentication mechanisms, and users can also implement extensions for access security validation.

Basic Authentication

To enable Basic authentication, modify the following configuration:

dubbo:
  provider:
    auth: true
    authenticator: basic
    username: admin
    password: admin

Once enabled, all HTTP requests will require Basic authentication to access.

If RPC calls are involved, the consumer side must also configure the corresponding username and password:

dubbo:
  consumer:
    auth: true
    authenticator: basic
    username: admin
    password: admin

With this configuration, communication between provider and consumer will use Basic authentication to ensure security. Please ensure strong passwords are used in production environments and consider using HTTPS for secure transmission.

Authentication Extensions

Implement Custom Authenticator

You can customize authentication using SPI org.apache.dubbo.auth.spi.Authenticator, and select the enabled Authenticator through configuration dubbo.provider.authenticator.

Implement HTTP Request Filtering

You can customize HTTP filter logic using SPI org.apache.dubbo.rpc.HeaderFilter or org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilter.

Global Parameter Configuration

Case Sensitivity

Configuration name: dubbo.protocol.triple.rest.case-sensitive-match
Whether path matching should be case-sensitive. If enabled, methods mapped to /users will not match /Users.
Default is true.

Tailing Matching

Configuration name: dubbo.protocol.triple.rest.trailing-slash-match
Whether path matching should match paths with trailing slashes. If enabled, methods mapped to /users will also match /users/.
Default is true.

Suffix Matching

Configuration name: dubbo.protocol.triple.rest.suffix-pattern-match
Whether path matching should use suffix pattern matching (.*); if enabled, methods mapped to /users will also match /users.*, and suffix content negotiation will also be enabled, with media types inferred from URL suffixes, such as .json corresponding to application/json.
Default is true.

CORS Configuration

Configuration Name Description Default Value
dubbo.protocol.triple.rest.cors.allowed-origins List of origins permitted for cross-domain requests; may be specific domains or the special value __representing all origins. Not set (no origins allowed)
dubbo.protocol.triple.rest.cors.allowed-methods List of allowed HTTP methods, such as GET, POST, PUT, etc.; a special value `` represents all methods. Not set (only GET and HEAD allowed)
dubbo.protocol.triple.rest.cors.allowed-headers List of allowed request headers for preflight requests; a special value __represents all headers. Not set
dubbo.protocol.triple.rest.cors.exposed-headers List of response headers that may be exposed to clients; a special value `` represents all response headers. Not set
dubbo.protocol.triple.rest.cors.allow-credentials Whether to support user credentials. Not set (user credentials not supported)
dubbo.protocol.triple.rest.cors.max-age Time (in seconds) that the response to a preflight request can be cached by the client. Not set

Advanced Usage Guide

Summary of Supported Extension Points

  1. javax.servlet.Filter
    Servlet API filters.
  2. org.apache.dubbo.rpc.protocol.tri.rest.support.servlet.HttpSessionFactory
    Supports HttpSession in Servlet API.
  3. javax.ws.rs.container.ContainerRequestFilter
    Implements request filters in JAX-RS, allowing for preprocessing requests before they reach resource methods.
  4. javax.ws.rs.container.ContainerResponseFilter
    Implements response filters in JAX-RS, allowing for post-processing of responses after they leave resource methods.
  5. javax.ws.rs.ext.ExceptionMapper
    Implements exception mappers in JAX-RS, mapping thrown exceptions to HTTP responses.
  6. javax.ws.rs.ext.ParamConverterProvider
    Provides parameter converters in JAX-RS, allowing for converting request parameters to resource method parameter types.
  7. javax.ws.rs.ext.ReaderInterceptor
    Implements reading interceptors in JAX-RS, allowing for interception and processing while reading request entities.
  8. javax.ws.rs.ext.WriterInterceptor
    Implements writing interceptors in JAX-RS, allowing for interception and processing while writing response entities.
  9. org.springframework.web.servlet.HandlerInterceptor
    Implements handler interceptors in Spring MVC.
  10. org.apache.dubbo.remoting.http12.ExceptionHandler
    Provides custom exception handling mechanisms.
  11. org.apache.dubbo.remoting.http12.message.HttpMessageAdapterFactory
    Provides matching and conversion features for HTTP messages.
  12. org.apache.dubbo.remoting.http12.message.HttpMessageDecoderFactory
    Provides decoding features for HTTP messages.
  13. org.apache.dubbo.remoting.http12.message.HttpMessageEncoderFactory
    Provides encoding features for HTTP messages.
  14. org.apache.dubbo.rpc.HeaderFilter
    Implements a header filter in Dubbo RPC, allowing for filtering and processing of request and response headers.
  15. org.apache.dubbo.rpc.protocol.tri.rest.filter.RestHeaderFilterAdapter
    Header filter adapter that provides access to HTTP input and output capabilities.
  16. org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilterAdapter
    Dubbo Filter REST adapter that provides access to HTTP input and output capabilities.
  17. org.apache.dubbo.rpc.protocol.tri.route.RequestHandlerMapping
    Implements request mapping capabilities in Dubbo Triple.
  18. org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMappingResolver
    Resolves REST request mappings.
  19. org.apache.dubbo.rpc.protocol.tri.rest.util.RestToolKit
    Provides REST-related utilities.
  20. org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentConverter
    Provides parameter type conversion features.
  21. org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentResolver
    Provides parameter resolution features.
  22. org.apache.dubbo.rpc.protocol.tri.rest.filter.RestFilter
    Provides filtering capabilities for REST requ

(本文超出站点单文档体积上限,已截断)