• 首页
  • 产品中心
    • 数式Oinone四大产品

      低代码开发平台无代码开发平台集成开发平台AI大模型开发
    • 数式Oinone体系能力

      用户与组织权限管理文件管理消息中心国际化业务审计
    • 数式Oinone核心产品特性

      低无一体面向软件公司场景无限制应用级扩容可分可合
  • 服务中心
    • 客户服务

      预约演示方案咨询私有部署找人定制
    • 开发者

      问答下载
    • Oinone学院

      社区学习

    《精讲面向软件公司的低代码平台——以Oinone为例》

  • 合作伙伴
    渠道申请伙伴名录专家库
  • 关于数式
0571-88757863

EIP API


I. Overview

The Oinone integration platform provides flexible interface definition capabilities through the annotations @Integrate and @Open, supporting efficient integration of internal and external enterprise systems.

  • @Open: Used to declare open interfaces for external system invocation.
  • @Integrate: Used to declare integration interfaces for invoking external system interfaces.

This document details the configuration items, usage scenarios, and examples of these two annotations.

Note

This document helps you quickly grasp core concepts and basic logic. However, during actual development, using the designer for auxiliary development is highly recommended. The designer provides a visual operation interface, simplifies configuration processes, reduces coding complexity, helps you complete development tasks more efficiently and accurately, and significantly improves development efficiency and quality.

II. Preparation Work

(Ⅰ) YAML Configuration

1. Open Platform Configuration

Related documentation on this topic can be found in "Integration Platform Configuration".

2. Start the eip Module

pamirs
  boot:
    modules:
      - eip
      -eip_mcp #is added as needed. If eip_mcp is included here, pamirs-eip2-mcp should be included in the pom of boot

(Ⅱ) Maven Dependencies

1. Add Relevant Dependencies to the api Project

Add the dependency on pamirs-eip2-api to xxxModule-api:

<dependency>
  <groupId>pro.shushi.pamirs.core</groupId>
  <artifactId>pamirs-eip2-api</artifactId>
</dependency>

2. Add Relevant Dependencies to the Startup Project

<dependency>
  <groupId>pro.shushi.pamirs.core</groupId>
  <artifactId>pamirs-eip2-core</artifactId>
</dependency>
<dependency>
  <groupId>pro.shushi.pamirs.core</groupId>
  <artifactId>pamirs-eip2-view</artifactId>
</dependency>
<dependency>
  <groupId>pro.shushi.pamirs.core</groupId>
  <artifactId>pamirs-eip2-designer</artifactId>
</dependency>

<!-- Version 6.3.0 provides eip2-mcp, which can be added as needed. If this is added here, this starts modules by increasing eip_mcp -->
<dependency>
  <groupId>pro.shushi.pamirs.core</groupId>
  <artifactId>pamirs-eip2-mcp</artifactId>
</dependency>

(Ⅲ) Add Module Dependencies to the Project's Module

Add dependency on EipModule to the xxxModule definition class:

@Module(dependencies = {EipModule.MODULE_MODULE})

III. @Open Annotation

(Ⅰ) Function Description

The @Open annotation defines open interfaces, allowing external systems to invoke them via HTTP requests. It supports configuring request methods, input/output converters, authentication processors, and other functions.

(Ⅱ) Annotation Structure

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Open {
    String name() default "";        // Interface display name
    Class<?> config() default Void.class; // Associated configuration class
    String path() default "";        // Interface path

    // Advanced configuration
    @interface Advanced {
        String httpMethod() default "post";                // HTTP method (default POST)
        String inOutConverterFun() default "";             // Input/output conversion function name
        String inOutConverterNamespace() default "";       // Input/output conversion function namespace
        String authenticationProcessorFun() default "";    // Authentication processing function name
        String authenticationProcessorNamespace() default ""; // Authentication processing function namespace
        String serializableFun() default "";               // Serialization function name
        String serializableNamespace() default "";         // Serialization function namespace
        String deserializationFun() default "";            // Deserialization function name
        String deserializationNamespace() default "";      // Deserialization function namespace
    }
}

Open

├── name Display name

├── config Configuration class

├── path Path

├── Advanced More configurations

│ ├── httpMethod Request method, default: post

│ ├── inOutConverterFun Input/output converter function name

│ ├── inOutConverterNamespace Input/output converter function namespace

│ ├── authenticationProcessorFun Authentication processor function name

│ ├── authenticationProcessorNamespace Authentication processor function namespace

│ ├── serializableFun Serialization function name

│ ├── serializableNamespace Serialization function namespace

│ ├── deserializationFun Deserialization function name

│ └── deserializationNamespace Deserialization function namespace

(Ⅲ) Usage Example

@Fun(TestOpenApiModelService.FUN_NAMESPACE)
@Component
public class TestOpenApiModelServiceImpl implements TestOpenApiModelService {
    @Function
    @Open(
        name = "Query Open Interface Data",
        path = "queryById4Open",
        config = TestEipConfig.class
    )
    @Open.Advanced(
        httpMethod = "post",
        authenticationProcessorFun = EipFunctionConstant.DEFAULT_AUTHENTICATION_PROCESSOR_FUN,
        authenticationProcessorNamespace = EipFunctionConstant.FUNCTION_NAMESPACE
    )
    public OpenEipResult<TestOpenApiResponse> queryById4Open(IEipContext<SuperMap> context) {
        // Business logic
        return result;
    }
}

(Ⅳ) Parameter Description

1. Member Variables

Variable NameTypeDefault ValueDescription
nameString""Interface display name
configClass<?>Void.classConfiguration class (needs to implement IEipAnnotationSingletonConfig
interface)
pathString""Interface request path

2. Nested Annotation @Advanced

Used to configure advanced options, can be annotated on methods or classes.

Variable NameTypeDefault ValueDescription
httpMethodString""HTTP request method (such as POST
)
inOutConverterFunString""Input/output converter function name
inOutConverterNamespaceString""Input/output converter namespace
authenticationProcessorFunString""Authentication processor function name
authenticationProcessorNamespaceString""Authentication processor namespace
serializableFunString""Serialization function name
serializableNamespaceString""Serialization function namespace
deserializationFunString""Deserialization function name
deserializationNamespaceString""Deserialization function namespace

IV. @Integrate Annotation

(Ⅰ) Function Description

The @Integrate annotation defines integrated interfaces, supporting invocation of external system open interfaces. It supports routing configuration, parameter conversion, exception handling, and other functions.

(Ⅱ) Annotation Structure

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Integrate {
    String name() default "";        // Interface display name
    Class<?> config();               // Associated configuration class (required)

    // Advanced configuration
    @interface Advanced {
        String host() default "";    // Target service domain name (e.g., "api.example.com")
        String path() default "";    // Target interface path (e.g., "/v1/data")
        String schema() default "";  // Protocol (e.g., "http" or "https")
        String httpMethod() default "post"; // HTTP method
    }

    // Request processor configuration
    @interface RequestProcessor {
        String finalResultKey() default "";  // Final request parameter key
        Integrate.ConvertParam[] convertParams() default {}; // Parameter mapping rules
        // Other configuration items (such as serialization, authentication processor, etc.)
    }

    // Response processor configuration
    @interface ResponseProcessor {
        String finalResultKey() default "";  // Final response result key
        // Other configuration items
    }

    // Exception processor configuration
    @interface ExceptionProcessor {
        String exceptionPredictFun() default "";     // Exception determination function name
        String exceptionPredictNamespace() default ""; // Exception determination function namespace
    }

    // Parameter mapping rules
    @interface ConvertParam {
        String inParam();   // Input parameter key
        String outParam();  // Output parameter key
    }
}

Integrate

├── name Display name

├── config Configuration class

├── Advanced More configurations

│ ├── host Request domain name + port

│ ├── path Request path starting with "/"

│ ├── schema Request protocol http or https

│ └── httpMethod Request method, default post

├── ExceptionProcessor Exception configuration

│ ├── exceptionPredictFun Exception determination function name

│ ├── exceptionPredictNamespace Exception determination function namespace

│ ├── errorMsg Exception determination Msg key

│ └── errorCode Exception determination errorCode key

├── RequestProcessor Request processing configuration

│ ├── finalResultKey Final result key of the request

│ ├── inOutConverterFun Input/output converter function name

│ ├── inOutConverterNamespace Input/output converter function namespace

│ ├── paramConverterCallbackFun Parameter conversion callback function name

│ ├── paramConverterCallbackNamespace Parameter conversion callback function namespace

│ ├── authenticationProcessorFun Authentication processor function name

│ ├── authenticationProcessorNamespace Authentication processor function namespace

│ ├── serializableFun Serialization function name

│ ├── serializableNamespace Serialization function namespace

│ ├── deserializationFun Deserialization function name

│ ├── deserializationNamespace Deserialization function namespace

│ └── convertParams Parameter conversion collection

│ └── ConvertParam Parameter conversion

│ ├── inParam Input parameter key

│ └── outParam Output parameter key

├── ResponseProcessor Request processing configuration

│ ├── finalResultKey Final result key of the response

│ ├── inOutConverterFun Input/output converter function name

│ ├── inOutConverterNamespace Input/output converter function namespace

│ ├── paramConverterCallbackFun Parameter conversion callback function name

│ ├── paramConverterCallbackNamespace Parameter conversion callback function namespace

│ ├── authenticationProcessorFun Authentication processor function name

│ ├── authenticationProcessorNamespace Authentication processor function namespace

│ ├── serializableFun Serialization function name

│ ├── serializableNamespace Serialization function namespace

│ ├── deserializationFun Deserialization function name

│ ├── deserializationNamespace Deserialization function namespace

│ └── convertParams Parameter conversion collection

│ └── ConvertParam Parameter conversion

│ ├── inParam Input parameter key

│ └── outParam Output parameter key

(Ⅲ) Usage Example

@Fun(TestIntegrateService.FUN_NAMESPACE)
@Component
public class TestIntegrateServiceImpl implements TestIntegrateService {
    @Override
    @Function
    @Integrate(
        name = "Invoke External Interface",
        config = TestEipConfig.class
    )
    @Integrate.Advanced(
        host = "api.oinone.com",
        path = "/data",
        schema = "https"
    )
    @Integrate.RequestProcessor(
        convertParams = {
            @Integrate.ConvertParam(inParam = "data.id", outParam = "id")
        }
    )
    public EipResult<SuperMap> callExternalService(TestOpenApiModel data) {
        return null; // Actually processed by the interceptor
    }
}

(Ⅳ) Parameter Description

1. Member Variables

Variable NameTypeDefault ValueDescription
nameString""Interface display name
configClass<?>NoneConfiguration class (must implement IEipAnnotationSingletonConfig
interface)

2. Nested Annotations

@Advanced

Configures basic request information.

Variable NameTypeDefault ValueDescription
hostString""Target service domain name and port
pathString""Request path
schemaString""Protocol type (such as http
or https
)
httpMethodString""HTTP request method (such as POST
)

@RequestProcessor

Configures request processing logic.

Variable NameTypeDefault ValueDescription
finalResultKeyString""Final request parameter key
convertParamsConvertParam[]{}Parameter mapping rules

@ConvertParam

Defines parameter mapping rules.

Variable NameTypeDescription
inParamStringInput parameter key
outParamStringOutput parameter key

V. Core Processing Functions

The integration platform extends interface behavior through the following functions:

Function TypeInterfaceDescription
inOutConverterIEipInOutConverterProcesses input/output conversion of request/response bodies
authenticationProcessorIEipAuthenticationProcessorImplements custom authentication logic (such as Token verification)
serializableIEipSerializableCustom serialization methods (such as XML, JSON)
exceptionProcessorIEipExceptionPredictCustom exception determination logic

VI. Complete Call Flow

(Ⅰ) Request Flow

(Ⅱ) Response Flow

Note

Perform md5 and encryption/decryption processing in IEipInOutConverter

VII. Register Open and Integrated Interfaces

(Ⅰ) Scan and Register All Interfaces Marked with @Open and @Integrate

Called during module startup lifecycle, related documentation on this topic can be found in "Module Lifecycle".

EipResolver.resolver(TestModule.MODULE_MODULE,null);
@Component
public class SecondModuleBizInit implements InstallDataInit, UpgradeDataInit, ReloadDataInit {

    @Override
    public boolean init(AppLifecycleCommand command, String version) {
        initEip();
        return Boolean.TRUE;
    }

    @Override
    public boolean reload(AppLifecycleCommand command, String version) {
        initEip();
        return Boolean.TRUE;
    }

    @Override
    public boolean upgrade(AppLifecycleCommand command, String version, String existVersion) {
        initEip();
        return Boolean.TRUE;
    }

    @Override
    public List<String> modules() {
        return Collections.singletonList(TestModule.MODULE_MODULE);
    }

    @Override
    public int priority() {
        return 0;
    }

    private void initEip() {
        EipResolver.resolver(TestModule.MODULE_MODULE,null);
    }
}

VIII. Examples

(Ⅰ) Notes

Note: config Configuration

  • Open Interface: config = TestEipConfig.class is used to set the general configuration class, where @Open.Advanced can be added, with priority lower than the annotation on the method.
  • Integrated Interface: Must use config = TestEipConfig.class to set the general configuration class, and @Integrate.Advanced can be added, with priority lower than the annotation on the method.

Note: Open Interface Fixed Path

http://localhost:8094/openapi/pamirs/yourPath

(Ⅱ) Open Interface Definition Examples

1. Basic Open Interface

Function: Define a query interface for external system invocation, supporting path parameters and basic authentication. Code Example:

@Fun(TestOpenApiModelService.FUN_NAMESPACE)
@Component
public class TestOpenApiModelServiceImpl implements TestOpenApiModelService {

    @Function
    @Open(
        path = "queryById4Open",
        config = TestEipConfig.class
    )
    @Open.Advanced(
        httpMethod = "post",
        authenticationProcessorFun = EipFunctionConstant.DEFAULT_NO_ENCRYPT_AUTHENTICATION_PROCESSOR_FUN,
        authenticationProcessorNamespace = EipFunctionConstant.FUNCTION_NAMESPACE
    )
    public OpenEipResult<TestOpenApiResponse> queryById4Open(IEipContext<SuperMap> context) {
        String id = context.getInterfaceContext().getIteration("id");
        TestOpenApiModel model = queryById(Long.valueOf(id));
        TestOpenApiResponse response = convertToResponse(model);
        return new OpenEipResult<>(response);
    }
}

Key Configurations:

  • @Open.path: Interface path is queryById4Open.
  • @Open.config: Associated with configuration class TestEipConfig.
  • @Open.Advanced.httpMethod: Uses POST method.
  • @Open.Advanced.authenticationProcessorFun: Enables unencrypted authentication.

2. Interface Exception Response Format

Function: Define an open interface returning exception information for testing error handling. Code Example:

@Function
@Open(path = "error")
@Open.Advanced(
    httpMethod = "post",
    authenticationProcessorFun = EipFunctionConstant.DEFAULT_NO_ENCRYPT_AUTHENTICATION_PROCESSOR_FUN
)
public OpenEipResult<TestOpenApiResponse> queryById4OpenError() {
    throw PamirsException.construct(EipExpEnumerate.SYSTEM_ERROR)
    .appendMsg("Test Exception")
    .errThrow();
}

Response Format:

{
  "success": false,
  "errorCode": "20140000",
  "errorMsg": "System Exception, Test Exception"
}

(Ⅲ) Integrated Interface Invocation Examples

1. Basic Integrated Interface

Function: Invoke external open interfaces, implementing parameter mapping and routing configuration. Code Example:

@Fun(TestIntegrateService.FUN_NAMESPACE)
@Component
public class TestIntegrateServiceImpl implements TestIntegrateService {

    @Override
    @Function
    @Integrate(config = TestEipConfig.class)
    @Integrate.Advanced(
        path = "/openapi/pamirs/queryById4Open",
        schema = "http",
        host = "127.0.0.1:8094"
    )
    @Integrate.RequestProcessor(
        convertParams = {
            @ConvertParam(inParam = "data.id", outParam = "id")
        }
    )
    public EipResult<SuperMap> callQueryByData(TestOpenApiModel data) {
        return null; // Actually processed by the interceptor
    }
}

Key Configurations:

  • @Integrate.config: Associated with configuration class TestEipConfig.
  • @Integrate.Advanced.path: Target interface path.
  • @Integrate.RequestProcessor.convertParams: Maps data.id to request parameter id.

2. Exception Handling Integrated Interface

Function: Invoke interfaces that may return exceptions and configure custom exception determination logic. Code Example:

@Function
@Integrate(config = TestEipConfig.class)
@Integrate.Advanced(path = "/openapi/pamirs/error?tenant=pamirs")
@Integrate.ExceptionProcessor(
    exceptionPredictFun = TestExceptionPredictFunction.FUN,
    exceptionPredictNamespace = TestExceptionPredictFunction.FUN_NAMESPACE
)
public EipResult<SuperMap> callQueryByIdError(TestOpenApiModel data) {
return null;
}

Custom Exception Determination Class:

@Fun(TestExceptionPredictFunction.FUN_NAMESPACE)
public class TestExceptionPredictFunction implements IEipExceptionPredict<SuperMap> {
    public static final String FUN_NAMESPACE ="test.TestExceptionPredictFunction";
    public static final String FUN ="testFunction";

    @Override
    @Function
    @Function.fun(FUN)
    public boolean test(IEipContext<SuperMap> context) {
        String errorCode = context.getExecutorContextValue("success");
        return "false".equals(errorCode); // Determine as exception
    }
}

(Ⅳ) Security Policy Configuration Examples

1. AccessToken Authentication

Function: Enable AccessToken authentication in open interfaces and automatically obtain tokens in integrated interfaces. Open Interface Configuration:

@Open.Advanced(
    authenticationProcessorFun = TestAuthFunction.FUN,
    authenticationProcessorNamespace = TestAuthFunction.FUN_NAMESPACE
)

Integrated Interface Authentication Processing Class:

@Component
@Fun(TestAuthFunction.FUN_NAMESPACE)
public class TestAuthFunction implements IEipAuthenticationProcessor<SuperMap> {
    public static final String FUN_NAMESPACE ="test.TestAuthFunction";
    public static final String FUN ="testAuthentication";

    @Override
    @Function
    @Function.fun(FUN)
    public boolean authentication(IEipContext<SuperMap> context,ExtendedExchange exchange) {
        // Get or apply for a new Token from Redis
        String token = redisTemplate.opsForValue().get("appKey");
        context.putInterfaceContextValue(IEipContext.HEADER_PARAMS_KEY + ".accessToken", token);
        return true;
    }
}

2. RSA Encrypted Communication

Function: Encrypt request parameters in integrated interfaces using RSA. Code Example:

@Integrate.RequestProcessor(
    inOutConverterFun = RSAInOutConverter.FUN,
    inOutConverterNamespace = RSAInOutConverter.FUN_NAMESPACE
)
public EipResult<EncryptedData> sendData(SensitiveRequest request) {
return null;
}

Encryption Processing Class:

@Fun(RSAInOutConverter.FUN_NAMESPACE)
@Component
public class RSAInOutConverter implements IEipInOutConverter {
    public static final String FUN_NAMESPACE ="test.RSAInOutConverter";
    public static final String FUN ="exchangeObject";

    @Override
    @Function
    @Function.fun(FUN)
    public Object exchangeObject(ExtendedExchange exchange, Object inObject) throws Exception{
        String encrypted = EncryptHelper.encryptByKey(publicKey, inObject.toString());
        return "{\"result\":\"" + encrypted + "\"}";
    }
}

(Ⅴ) Custom Serialization Examples

1. XML Serialization

Function: Implement parsing of response data in XML format. Code Example:

@Integrate.ResponseProcessor(
    serializableFun = TestSerializableFunction.FUN,
    serializableNamespace = TestSerializableFunction.FUN_NAMESPACE
)
public EipResult<XmlData> parseXmlResponse() {
    return null;
}

XML Serialization Class:

public class TestSerializableFunction implements IEipSerializable<SuperMap> {
    public static final String FUN_NAMESPACE ="test.TestSerializableFunction";
    public static final String FUN ="xmlParser";

    @Override
    @Function.Advanced(displayName = "Custom XML Serialization Method")
    @Function.fun(FUN)
    public SuperMap serializable(Object inObject) {
        if (inObject == null) {
            return new SuperMap();
        } else {
            SuperMap result;
            if (inObject instanceof String) {
                String inObjectString = (String)inObject;
                if (StringUtils.isNotBlank(inObjectString)) {
                    result = this.stringToSuperMap(inObjectString);
                } else {
                    result = new SuperMap();
                }
            } else if (inObject instanceof InputStream) {
                result = this.inputStreamToString((InputStream)inObject);
            } else if (inObject instanceof SuperMap) {
                result = (SuperMap) inObject;
            }
            else{
                result = new SuperMap();
            }
            return result;
        }
    }

    protected SuperMap inputStreamToString(InputStream inputStream) {
        StringBuilder sb = new StringBuilder();
        String line;
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {
            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line);
            }
            return serializable(sb.toString());
        } catch (IOException e) {
            return new SuperMap();
        }
    }


    protected SuperMap stringToSuperMap(String s) {
        SuperMap result = new SuperMap();
        try {
            Document document = DocumentHelper.parseText(s);
            Element root = document.getRootElement();
            iterateNodes(root, result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static void iterateNodes(Element node, SuperMap superMap){
        //Get the name of the current element
        String nodeName = node.getName();
        if(superMap.containsKey(nodeName)){
            //There are multiple instances of this element at the same level
            Object object = superMap.getIteration(nodeName);
            List<Object> list = Lists.newArrayList();
            if(object instanceof JSONArray){
                list = (List) object;
            }else {
                list = Lists.newArrayList();
                list.add(object);
            }
            //Get all sub-elements under this element
            List<Element> listElement = node.elements();
            if(listElement.isEmpty()){
                //This element has no sub-elements, get the element's value
                String nodeValue = node.getTextTrim();
                list.add(nodeValue);
                superMap.putIteration(nodeName, list);
                return;
            }
            //Has sub-elements
            SuperMap subMap = new SuperMap();
            //Traverse all sub-elements
            for(Element e:listElement){
                //Recursion
                iterateNodes(e, subMap);
            }
            list.add(subMap);
            subMap.putIteration(nodeName, list);
            return;
        }
        List<Element> listElement = node.elements();
        if(listElement.isEmpty()){
            //This element has no sub-elements, get the element's value
            String nodeValue = node.getTextTrim();
            superMap.putIteration(nodeName, nodeValue);
            return;
        }
        //Has child nodes, create a new JSONObject to store the values of the child nodes under this node
        SuperMap subMap = new SuperMap();
        //Traverse all first-level child nodes
        for(Element e:listElement){
            //Recursion
            iterateNodes(e, subMap);
        }
        superMap.putIteration(nodeName, subMap);
    }

}

Note: The example includes the dom4j dependency

Edit this page
Last Updated:1/15/26, 4:02 AM
Prev
Resources API
Next
Common Extension Points And SPI List
默认页脚
Copyright © 2026 Mr.Hope