Design Component Data

Component data is designed based on the functions provided by your component. Our example will implement user creation, query and modification.Each user has two data fields: name and age.
struct Profiles{
  string name;
  uint256 age;
}
mapping (address=>Profiles) users;

Initialization Method Data Type

Initialize the methods you provide in the constructor. We initialize three request methods: GET request:
getUser, obtains the user’s name and age.
POST request:
createUser, creates a user.
PUT request:
updateUserName, updates the user’s name.
constructor(){
  Types.Type[] memory getReqArray = new Types.Type[](1);
  getReqArray[0] = Types.Type.ADDRESS;
  Types.Type[] memory dataTypeArray = new Types.Type[](2);
  dataTypeArray[0] = Types.Type.STRING;
  dataTypeArray[1] = Types.Type.UINT256;
  Types.Type[] memory putReqArray = new Types.Type[](2);
  putReqArray[0] = Types.Type.ADDRESS;
  putReqArray[1] = Types.Type.STRING;
  setMethod("getUser",MethodTypes.GET,getReqArray,dataTypeArray,"obtains the user's name and age");
  setMethod("createUser",MethodTypes.POST,dataTypeArray,new Types.Type[](0),"creates a user.");
  setMethod("updateUserName",MethodTypes.PUT,putReqArray,new Types.Type[](0),"updates the user's name.");
}
Function used to set method.
    function setMethod(
        string memory _methodName,
        MethodTypes _methodType,
        Types.Type[] memory _methodReq,
        Types.Type[] memory _methodRes,
        string memory _instruction
    ) private {
        methods[_methodType].push(_methodName);
        methodRequests[_methodName] = _methodReq;
        methodResponses[_methodName] = _methodRes;
        instructions[_methodName] = _instruction;
    }

Implement Request Methods

Implement each request method in GET, POST, and PUT.
   function get(string memory _methodName,bytes memory _methodReq)public view returns(bytes memory){
        if(compareStrings(_methodName,"getUser")){
            address user=abi.decode(_methodReq, (address));
            bytes memory userData=abi.encode(users[user].name,users[user].age);
            return userData;
        }else{
            return abi.encode("");
        }  
    }

    function post(string memory _methodName,bytes memory _methodReq)public payable returns(bytes memory){
        if(compareStrings(_methodName,"createUser")){
            (string memory name,uint256 age)=abi.decode(_methodReq, (string,uint256));
            users[msg.sender]=Profiles(name,age);
            bytes memory resBytes=abi.encode(name,age);
            emit  Response(resBytes);
            return resBytes;
        }
        return abi.encode("");
    }

    function put(string memory _methodName,bytes memory _methodReq)public payable returns(bytes memory){
        if(compareStrings(_methodName,"updateUserName")){
            (address userAddress,string memory name)=abi.decode(_methodReq, (address,string));
            require(userAddress==msg.sender);
            users[userAddress].name=name;
        }
        return abi.encode("");
    }
Function used to compares two strings for equality.
    function compareStrings(string memory _a, string memory _b)
        private
        pure
        returns (bool)
    {
        return
            keccak256(abi.encodePacked(_a)) == keccak256(abi.encodePacked(_b));
    }

Put them together

Example.sol
// SPDX-License-Identifier: CC0-1.0
pragma solidity >=0.8.0;
import "../../Ame/Types.sol";
import "../../Ame/IComponent.sol";

contract Component is IComponent {
    //@dev Types contains all data types in solidity
    mapping(string => Types.Type[]) methodRequests;
    mapping(string => Types.Type[]) methodResponses;
    mapping(MethodTypes => string[]) methods;
    mapping(string => string) instructions;

    //@dev define the data type of this component
    struct Profiles {
        string name;
        uint256 age;
    }
    mapping(address => Profiles) users;

    constructor() {
        Types.Type[] memory getReqArray = new Types.Type[](1);
        getReqArray[0] = Types.Type.ADDRESS;
        Types.Type[] memory dataTypeArray = new Types.Type[](2);
        dataTypeArray[0] = Types.Type.STRING;
        dataTypeArray[1] = Types.Type.UINT256;
        Types.Type[] memory putReqArray = new Types.Type[](2);
        putReqArray[0] = Types.Type.ADDRESS;
        putReqArray[1] = Types.Type.STRING;
        // @dev initialize get, post, put request parameter data types and response data types
        setMethod(
            "getUser",
            MethodTypes.GET,
            getReqArray,
            dataTypeArray,
            "get user profiles"
        );
        setMethod(
            "createUser",
            MethodTypes.POST,
            dataTypeArray,
            dataTypeArray,
            "Create user profiles"
        );
        setMethod(
            "updateUserName",
            MethodTypes.PUT,
            putReqArray,
            new Types.Type[](0),
            "Update user information"
        );
    }

    function get(string memory _methodName, bytes memory _methodReq)
        public
        view
        returns (bytes memory)
    {
        if (compareStrings(_methodName, "getUser")) {
            address user = abi.decode(_methodReq, (address));
            bytes memory userData = abi.encode(
                users[user].name,
                users[user].age
            );
            return userData;
        } else {
            return abi.encode("");
        }
    }

    function post(string memory _methodName, bytes memory _methodReq)
        public
        payable
        returns (bytes memory)
    {
        if (compareStrings(_methodName, "createUser")) {
            (string memory name, uint256 age) = abi.decode(
                _methodReq,
                (string, uint256)
            );
            users[msg.sender] = Profiles(name, age);
            bytes memory resBytes = abi.encode(name, age);
            emit Response(resBytes);
            return resBytes;
        }
        return abi.encode("");
    }

    function put(string memory _methodName, bytes memory _methodReq)
        public
        payable
        returns (bytes memory)
    {
        if (compareStrings(_methodName, "updateUserName")) {
            (address userAddress, string memory name) = abi.decode(
                _methodReq,
                (address, string)
            );
            require(userAddress == msg.sender);
            users[userAddress].name = name;
        }
        return abi.encode("");
    }

    function options() public pure returns (MethodTypes[] memory) {
        MethodTypes[] memory methodTypes = new MethodTypes[](3);
        methodTypes[0] = MethodTypes.GET;
        methodTypes[1] = MethodTypes.POST;
        methodTypes[2] = MethodTypes.PUT;
        return methodTypes;
    }

    function setMethod(
        string memory _methodName,
        MethodTypes _methodType,
        Types.Type[] memory _methodReq,
        Types.Type[] memory _methodRes,
        string memory _instruction
    ) private {
        methods[_methodType].push(_methodName);
        methodRequests[_methodName] = _methodReq;
        methodResponses[_methodName] = _methodRes;
        instructions[_methodName] = _instruction;
    }

    function getMethodReqAndRes(string memory _methodName)
        public
        view
        returns (Types.Type[] memory, Types.Type[] memory)
    {
        return (methodRequests[_methodName], methodResponses[_methodName]);
    }

    function getMethods(MethodTypes _methodTypes)
        public
        view
        returns (string[] memory)
    {
        return methods[_methodTypes];
    }

    function getMethodInstruction(string memory _methodName)
        public
        view
        returns (string memory)
    {
        return instructions[_methodName];
    }

    //@dev compares two strings for equality
    function compareStrings(string memory _a, string memory _b)
        private
        pure
        returns (bool)
    {
        return
            keccak256(abi.encodePacked(_a)) == keccak256(abi.encodePacked(_b));
    }
}