Is it a gimmick or a myth to develop local API s for external system calls without writing any WEB code?

Keywords: C# SQL

First, let's simulate a business scenario. If we have such a master data table:

In order to find the information of this master data, we let each field participate in the query:

  The category is master data:

Now you need to develop an API locally to call external systems.

  1. Transmission mode: POST
  2. The data format of request and response is JSON

In order to realize zero code development, we need to use a software tool: fast allocation.

  1. Fast configuration is a set of business rapid configuration system to help software developers realize low code development;
  2. Fast download address: Fast download 

Step 1: create a stored procedure for query in the database. (using Microsoft SQL Server database)

CREATE PROCEDURE [dbo].[SPDEMO_network_Parametric query]
	@fcode nvarchar(50),
	@fname nvarchar(50),
	@ftype nvarchar(10),
	@fdatefrom datetime,
	@fdateto datetime,
	@fqtyfrom int,
	@fqtyto int,
	@famountfrom float,
	@famountto float
AS
BEGIN
	SELECT 
	   [FID]
      ,[code]
      ,[name]
      ,[category]
      ,[Application date]
      ,[quantity]
      ,[amount of money] 
	FROM DEMO_Picture data
	WHERE 
		code LIKE '%'+ISNULL(@fcode,'')+'%' AND
		name LIKE '%'+ISNULL(@fname,'')+'%' AND
		category LIKE '%'+ISNULL(@ftype,'')+'%' AND
		CONVERT(NVARCHAR(10),Application date,120) >= CONVERT(NVARCHAR(10),ISNULL(@fdatefrom,'1900-01-01 00:00:00'),120) AND
		CONVERT(NVARCHAR(10),Application date,120) <= CONVERT(NVARCHAR(10),ISNULL(@fdateto,'2999-12-31 23:59:59'),120) AND
		quantity>=ISNULL(@fqtyfrom,-999999) AND
		quantity<=ISNULL(@fqtyto,999999) AND
		amount of money>=ISNULL(@famountfrom,-999999999.99) AND
		amount of money<=ISNULL(@famountto,999999999.99) AND
		CONVERT(NVARCHAR(4),Application date,120) = '2019'

	ORDER BY code
END

Step 2: create an object in the match fast software:

 

  The process of creating an object is very simple. Select the data for it from the database stored procedure, and set the WEB access ID.

The WEB access identifier, which is the key, is the addressing parameter for the external system to access the local API.

Step 3: configure query parameters for this object:

  Step 4: when executing the stored procedure to return the data result set, it will be displayed in the data table of the business interface; If you need to style the data in the data table, you must configure the return column in fast allocation; Otherwise, you can omit this step.

  Step 5: publish the configured object to the business system interface for developers to test and view the effect. If you do not need testing, you can omit this step.

  Here, the local self built API is over.

Now, start testing the effect of the configuration. First in business main interface:

Find the newly published object, double-click the object to open the filter interface, select the category of "Outgoing", and do not set the rest (simple example), and then click OK to start query. You can find several records.

  If the records can be queried to explain the self built API and the internal process is unobstructed, there will be no problems with external system calls.

After all, you need to provide a URL for external system access. If the domain name is peidekuai.com

Then the URL accessed by the external system is: http://www.peidekuai.com/read.ashx?id=125

"125" here is the "WEB access ID" mentioned above. read.ashx is a general processing program used to read data.

Now there is an external system 1000 kilometers away from you. Start to access the API just built.

Access address: http://www.peidekuai.com/read.ashx?id=125

POST data:

{"fcode":"","fname":"","ftype":"Outgoing","fdatefrom":"","fdateto":"","fqtyfrom":"","fqtyto":"","famountfrom":"","famountto":""}

Response data after execution:

{"success":"true","errorcode":"0","error":"","data":[{"FID":"3BF6657E-6B01-4785-B3D1-1A771332B416","code":"KWF17-00C3222","name":"Wet zone guide shaft","category":"Outgoing","Application date":"2019-04-27 18:45:30","quantity":"410","amount of money":"530"},{"FID":"57652799-016F-424E-B7D7-5DD56A30084D","code":"KWF17-00W0103","name":"Stub shaft support seat","category":"Outgoing","Application date":"2019-04-30 18:45:31","quantity":"440","amount of money":"620"},{"FID":"8E737E47-1B87-472C-A1D1-3A8D3684DB3B","code":"KWF17-00W0203","name":"Metal conveying shaft 1","category":"Outgoing","Application date":"2019-05-03 18:45:31","quantity":"470","amount of money":"710"},{"FID":"CADC5066 ...

The returned response data is in JSON format, which seems a little difficult. It is more intuitive for us to convert it into a table:

  The returned data is consistent with the results of the previous test.

This shows that using fast configuration comes from building API interfaces, and there is really no need to write any WEB code. Next, let's analyze how fast matching works.

using System;
using System.IO;
using System.Text;
using System.Web;
using PDK.Core;
using PDK.Log;

namespace PDK.Web
{
    /// <summary>
    ///Read WEB data
    /// </summary>
    public class read : IHttpHandler
    {
        /// <summary>
        ///Read WEB data
        /// </summary>
        public read() { }

        /// <summary>
        ///Start processing client requests
        /// </summary>
        /// <param name="context"></param>
        public void ProcessRequest(HttpContext context)
        {
            string strResponseContentType = null;
            string strSuccessResponseText = null;
            string strFailureResponseText = null;
            string strUrlParamID = null;
            try
            {
                DateTime tmBeginTime = DateTime.Now;
                string strTimeLogInfo = "Network read request received,Start processing time:" + tmBeginTime.ToString("yyyy-MM-dd HH:mm:ss:ffff");
                LogWriter.WriteInfo(strTimeLogInfo);

                strUrlParamID = context.Request["id"];
                if (string.IsNullOrEmpty(strUrlParamID) == true)
                    throw new Exception("Of network read requests URL wrongful(URL in id Missing parameter,The system needs to be based on this id Parameter values to determine how data should be read).");

                string strNetworkData = null;
                using (Stream smNetworkStream = context.Request.InputStream)
                {
                    if (smNetworkStream.Length > 0)
                    {
                        byte[] arNetworkStreamBytes = new byte[smNetworkStream.Length];
                        smNetworkStream.Read(arNetworkStreamBytes, 0, (int)arNetworkStreamBytes.Length);
                        strNetworkData = Encoding.UTF8.GetString(arNetworkStreamBytes); 
                    }
                }

                DateTime tmNetworkDataTime = DateTime.Now;
                strTimeLogInfo = "Time consuming to receive network data:" + (tmNetworkDataTime - tmBeginTime).TotalMilliseconds.ToString() + "millisecond";
                LogWriter.WriteInfo(strTimeLogInfo);

                string strTaskID = PDK.Common.Global.NewGuid;
                LogWriter.WriteInfo("Data processing started[task number:" + strTaskID + "]...");

                string strResponseData = ApiWebPublic.WebReadData(strTaskID, strUrlParamID, strNetworkData, context, out strResponseContentType);

                DateTime tmResponseDataTime = DateTime.Now;
                LogWriter.WriteInfo("End of data processing,time consuming:" + (tmResponseDataTime - tmNetworkDataTime).TotalMilliseconds.ToString() + "millisecond");

                string strLogData = ApiWebPublic.GetLogData(strResponseData);
                LogWriter.WriteInfo("Return value after processing:" + strLogData + "\r\n");

                context.Response.ContentType = strResponseContentType;
                context.Response.Write(strResponseData);
            }
            catch (Exception exp)
            {
                LogWriter.WriteError("An unexpected error occurred during the network read request processing phase:\r\n" + exp.Message + "\r\n");

                ApiWebPublic.ReadApiResponseText(strUrlParamID, ref strResponseContentType, ref strSuccessResponseText, ref strFailureResponseText);

                //Return execution result
                context.Response.ContentType = strResponseContentType;
                context.Response.Write(ApiWebPublic.GetApiResponseData(strFailureResponseText, exp.Message, null));
            }
        }

        /// <summary>
        ///Allow WEB services to create multiple instances
        /// </summary>
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

In this code, there is a method WebReadData (). Let's look at the implementation code of this method:

        /// <summary>
        ///Read data from the database or public interface and return it to the WEB caller
        /// </summary>
        ///< param name = "taskid" > task No. < / param >
        ///< param name = "urlparamid" > Web access ID < / param >
        ///< param name = "requestdata" > received network data < / param >
        ///< param name = "webhttpcontext" > HTTP operation object for network access < / param >
        ///< param name = "responsecontenttype" > content type of response < / param >
        ///< returns > returns the response content after execution < / returns >
        public static string WebReadData(string taskId, string urlParamID, string requestData, HttpContext webHttpContext, out string responseContentType)
        {
            responseContentType = DefaultResponseContentType; //The default is Json

            LogWriter.WriteInfo("WEB Access ID:id={0}", urlParamID);
            LogWriter.WriteInfo("WEB Request data:{0}", GetLogData(requestData));

            DbSessionInfo dbInfo = new DbSessionInfo();
            dbInfo.dbs = new DbSession();

            //Find the configured object according to the WEB access ID
            //================================================================================================
            DataTable dtObject = ApiDb.QueryObjectByUrlParamID(urlParamID, dbInfo.dbs, dbInfo.DbBuffer);
            if (dtObject == null || dtObject.Rows.Count == 0)
                throw new Exception("WEB The access ID is invalid or does not exist(WEB Access ID: " + urlParamID + ").");

            ObjectInfo objInfo = new ObjectInfo(dtObject.Rows[0]);
            dtObject = null;
            //================================================================================================

            CheckWebPassword(webHttpContext, objInfo.FWebPassword);

            if (objInfo.FResponseContentType != null)
                responseContentType = objInfo.FResponseContentType; 

            if (objInfo.FRequestDataFormat == null) 
                objInfo.FRequestDataFormat = "json";
            if (objInfo.FResponseDataFormat == null) 
                objInfo.FResponseDataFormat = "json";
            if (objInfo.FSuccessText == null)
                objInfo.FSuccessText = DefaultSuccessResponseText;
            if (objInfo.FFailureText == null)
                objInfo.FFailureText = DefaultFailResponseText;

            LogWriter.WriteInfo("Found WEB The object to which the access ID is associated:{0}(id={1})", objInfo.FObjectDesc, objInfo.FObjectID);

            try
            {
                //Preprocess the data if necessary
                string strPostData = requestData;
                if (objInfo.FWebRequestInitFunName != null) //Preprocessing function exists
                {
                    //Request preprocessing function
                    strPostData = WebRequestDataInit(objInfo, requestData, webHttpContext);
                    LogWriter.WriteInfo("WEB The requested data needs to be preprocessed,Preprocessed result data:{0}", GetLogData(strPostData));
                }

                //Convert JSON/XML into row and column data that can be recognized by the system
                DataSet dsConvertedPostData = null;
                if (strPostData != null)
                {
                    //1 = convert to DataSet
                    //2 = convert to tree
                    //3 = convert to string
                    string strFRequestDataFormat = objInfo.FRequestDataFormat.ToLower();
                    if (objInfo.FWebDisplayType <= 1) //Convert JSON/XML string to dataset (DateSet)
                    {
                        if (strFRequestDataFormat.Equals("json") == true)
                            dsConvertedPostData = DynamicJson.ParseJsonToDataSet(strPostData);
                        else if (strFRequestDataFormat.Equals("xml") == true)
                        {
                            DynamicXml dxml = new DynamicXml(strPostData);
                            dsConvertedPostData = dxml.ParseXmlToDataSet();
                            dxml = null;
                        }
                    }
                    else if (objInfo.FWebDisplayType == 3) //JSON/XML string
                    {
                        if (strFRequestDataFormat.Equals("json") == true)
                            dsConvertedPostData = DynamicJson.ParseJsonToStringDataSet(strPostData);
                        else if (strFRequestDataFormat.Equals("xml") == true)
                            dsConvertedPostData = DynamicXml.StaticParseXmlToStringDataSet(strPostData);
                    }
                    else  //Convert JSON/XML string to tree (tree display)
                        throw new Exception("\"" + objInfo.FObjectDesc + "\"of JSON/XML Data conversion mode configuration error,Not supported here\"JSON/XML String to tree(Tree display)\".");

                    strPostData = null;
                }

                DataSet dsResultData = OpenObject(objInfo, null, dsConvertedPostData, webHttpContext, dbInfo);

                string strResponseData = null;
                if (dsResultData != null && dsResultData.Tables.Count > 0)
                {
                    if (objInfo.FResponseDataFormat.ToLower().Equals("json") == true)
                        strResponseData = DynamicJson.ParseDataSetToJson(dsResultData);
                    else if (objInfo.FResponseDataFormat.ToLower().Equals("xml") == true)
                        strResponseData = DynamicXml.StaticParseDataSetToXml(dsResultData);
                }

                if (strResponseData == null)
                {
                    LogWriter.WriteInfo("WEB Response data:{0}", "(Null value)");
                }
                else
                {
                    LogWriter.WriteInfo("WEB Response data:{0}", GetLogData(strResponseData));

                    if (objInfo.FWebResponseInitFunName != null)
                    {
                        strResponseData = WebResponseDataInit(objInfo, strResponseData, webHttpContext);
                        LogWriter.WriteInfo("WEB The response data needs special processing,Result data after special processing:{0}", GetLogData(strResponseData));
                    }
                }
                return GetApiResponseData(objInfo.FSuccessText, "", strResponseData);
            }
            catch (Exception exp)
            {
                return GetApiResponseData(objInfo.FFailureText, exp.Message, null);
            }
        }

  When the external system accesses the self built API, the above code will be executed. Let's look at the WEB log after code execution:

2021-09-14 11:47:14,054 [7] INFO  - Network read request received,Start processing time:2021-09-14 11:47:13:9529
2021-09-14 11:47:14,064 [7] INFO  - Time consuming to receive network data:112.0064 millisecond
2021-09-14 11:47:14,064 [7] INFO  - Data processing started[task number:21091411471406495F560E824AB3465F]...
2021-09-14 11:47:14,071 [7] INFO  - WEB Access ID:id=125
2021-09-14 11:47:14,072 [7] INFO  - WEB Request data:{"fcode":"","fname":"","ftype":"Outgoing","fdatefrom":"","fdateto":"","fqtyfrom":"","fqtyto":"","famountfrom":"","famountto":""}
2021-09-14 11:47:14,100 [7] INFO  - Found WEB The object to which the access ID is associated:Network demonstration-Self built interface-POST visit-Have reference-Direct access(id=2107231134417406E1B243D407544C2B)
2021-09-14 11:47:14,138 [7] INFO  - WEB Response data:[{"FID":"3BF6657E-6B01-4785-B3D1-1A771332B416","code":"KWF17-00C3222","name":"Wet zone guide shaft","category":"Outgoing","Application date":"2019-04-27 18:45:30","quantity":"410","amount of money":"530"},{"FID":"57652799-016F-424E-B7D7-5DD56A30084D","code":"KWF17-00W0103","name":"Stub shaft support seat","category":"Outgoing","Application date":"2019-04-30 18:45:31","quantity":"440","amount of money":"620"},{"FID":"8E737E47-1B87-472C-A1D1-3A8D3684DB3B","code":"KWF17-00W0203","name":"Metal conveying shaft 1","category":"Outgoing","Application date":"2019-05-03 18:45:31","quantity":"470","amount of money":"710"},{"FID":"CADC5066-F63A-4A2C-A70C-DF1AE77E62A6","code":"KWF17-00W0205"," ...
2021-09-14 11:47:14,139 [7] INFO  - End of data processing,time consuming:75.0043 millisecond
2021-09-14 11:47:14,139 [7] INFO  - Return value after processing:{"success":"true","errorcode":"0","error":"","data":[{"FID":"3BF6657E-6B01-4785-B3D1-1A771332B416","code":"KWF17-00C3222","name":"Wet zone guide shaft","category":"Outgoing","Application date":"2019-04-27 18:45:30","quantity":"410","amount of money":"530"},{"FID":"57652799-016F-424E-B7D7-5DD56A30084D","code":"KWF17-00W0103","name":"Stub shaft support seat","category":"Outgoing","Application date":"2019-04-30 18:45:31","quantity":"440","amount of money":"620"},{"FID":"8E737E47-1B87-472C-A1D1-3A8D3684DB3B","code":"KWF17-00W0203","name":"Metal conveying shaft 1","category":"Outgoing","Application date":"2019-05-03 18:45:31","quantity":"470","amount of money":"710"},{"FID":"CADC5066 ...

The above shows only the fast entry code. In a word, match fast has integrated all WEB codes into its system. Developers only need to pay attention to the preparation of database SQL script instead of spending energy on writing WEB code, which is really very labor-saving.

In this way, with the help of fast matching software, developing local API s to call external systems without writing any WEB code is not a gimmick, but can be really realized.

It is said that the API with fast access to external systems can also be developed without writing code. On average, the development of an external API can be completed in 10 minutes. This article will not continue to expand, but write another article to introduce it in detail.

Thank you for your appreciation!

[end of article]

Posted by busyguy78 on Sun, 19 Sep 2021 06:44:42 -0700