Newsgroups: bit.listserv.edi-l
Date:         Thu, 20 Aug 1992 09:42:39 -0700
From:         Bill Laidley <WLAIDLEY@BCSC02.BITNET>
Subject:      RE: API's ???

 Randall,

 An application programming interface (API) is a set of function calls. You
 pass arguments to the function, and a value is returned. This is similar to
 your approach, which is to allow Pro_EDI to be 'executed by other applications
 programs, from batch files...'. The KEY difference is that the API is a
 function rather than just a call to another program. I'll break with the
 tradition of this list and show some sample code from a system I developed.

 (My apologies to IBM if my explanations of how the OS/2 API's work aren't
 strictly correct...)

 ******** Start of included source code *********************************

   /*********************************************************/
   /* Setup database manager connections first              */
   /* Note: copied from the ibm manual                      */
   /*********************************************************/

   /**********************************************************/
   /* The RxFuncQuery is internal to OS/2 REXX - it tests to */
   /* see if API function modules are loaded into memory.    */
   /* Test connection to SQLDBS services - load if required */
   /* SQLDBS services allow connecting to the Database      */
   /* Manager                                               */
   /*********************************************************/

   if RxFuncQuery('SQLDBS') <> 0 then
     /**********************************************************/
     /* The RxFuncAdd is internal to OS/2 REXX - it loads the  */
     /* API function modules and establishes the required      */
     /* 'connections'.                                         */
     /**********************************************************/
     rcy = RxFuncAdd('SQLDBS', 'SQLAR', 'SQLDBS')

   /*************************************************************/
   /* Test connection to SQLEXEC services - load if required    */
   /* SQLEXEC services allow the program to run SQL statements. */
   /*************************************************************/

   if RxFuncQuery('SQLEXEC') <>0 then
     rcy = RxFuncAdd('SQLEXEC', 'SQLAR', 'SQLEXEC')

   SetUp_rc = 0

   say 'Linking to Database Manager....'
   call SQLDBS 'START DATABASE MANAGER'

   /*************************************************/
   /* One of the functions of the initialisation    */
   /* API call is to create the SQLCA - AKA the     */
   /* SQL communications area - a set of variables  */
   /* for passing data back to the calling program. */
   /*************************************************/

   if SQLCA.SQLCODE <> -1026 & SQLCA.SQLCODE <> 0 then
     do
       say SQLMSG
       ErrMsg = 'Error occurred while linking to Database Manager.'
       signal START_ERROR
     end

   /***********************************************************/
   /* Completion of program. Restore the environment and free */
   /* the memory used by Database Manager and API modules.    */
   /***********************************************************/

   FINISH:

      call SQLDBS 'STOP USING DATABASE'
      call SQLDBS 'STOP DATABASE MANAGER'
      rcy = RxFuncDrop('SQLEXEC')
      rcy = RxFuncDrop('SQLDBS')
      ErrMsg = ''

   /**************************************************************/
   /* CREATE_TABLE:  this sub-routine is used to create an SQL   */
   /* table, the index, and to add a comment to identify the use */
   /* of the table.                                              */
   /**************************************************************/

   CREATE_TABLE:

     Stmt = 'DROP TABLE CEIRS12'
     call MAKE_SQL_CALL

     Stmt = 'CREATE TABLE CEIRS12 ',
              '(LOADED  CHAR(6) NOT NULL,',
               'FILENUM  CHAR(7) NOT NULL,',
               'XREFNUM  CHAR(7) NOT NULL,',
               'XREFTYPE CHAR(1) NOT NULL)'
     call MAKE_SQL_CALL

     Stmt = 'CREATE UNIQUE INDEX CEIRS12_NDX ',
            'ON CEIRS12 (LOADED, FILENUM, XREFNUM, XREFTYPE)'
     call MAKE_SQL_CALL

     Stmt = "COMMENT ON TABLE CEIRS12 IS ",
            "'Cross reference of entity relationships'"
     call MAKE_SQL_CALL

   RETURN /* to calling routine */

   /*******************************************************/
   /* MAKE_SQL_CALL uses the value in the variable Stmt   */
   /* as a command to Database Manager.                   */
   /* Tested. 90/11/20  Bill Laidley                      */
   /*******************************************************/

   MAKE_SQL_CALL:

     /**********************************************/
     /* call the function to run the SQL statement */
     /**********************************************/

     call SQLEXEC 'EXECUTE IMMEDIATE :Stmt'

     if SQLCA.SQLCODE < 0 then /**************************************/
                               /* an SQLCODE > 0 is an information   */
                               /* statement. An error did not occur. */
                               /**************************************/
       do
         Task = 'Error occured creating table '  TName
         call DUMP_SQL_ERROR Stmt, Task
       end

     call SQLEXEC 'COMMIT'
     if SQLCA.SQLCODE < 0 then
       do
         Task = 'Error occured during commit'
         call DUMP_SQL_ERROR Stmt, Task
       end
     Stmt = ''

   RETURN /* to calling routine */

 ******** End of included source code ***********************************

 The key thing to note as a difference is that rather than calling an
 entire program, we are calling modules which, for the most part, are
 designed to do one thing only. So, if for example you rewrote Pro_EDI
 to allow API use, there would be ONE module for EDI translation, ONE
 module for interchange generation, ONE module for incoming message
 auditing, ONE module for document management (to use your examples),
 and so on.

 Each module would take one or more parameters to pass data and control
 information. On completion each module would return a code to indicate
 success or failure.

 The architectural impact of this is the Pro_EDI (that we know and love)
 would become a smaller program which calls the API modules. This allows
 interactive use of Pro_EDI. If, however, I wanted to add EDI functions to
 my purchasing system (just an example folks...) I could call those same
 API modules directly from my application without calling Pro_EDI (the
 user interface) at all. Now in the MS-DOS world the operating system
 doesn't support this kind of thing too well. But in Windows, OS/2 (and
 the operating systems associated with Mini's and Mainframes) the API
 modules are dynamically linked when called. At the cost of adding some
 additional overhead (loading and unloading the API modules as required)
 you reduce overall memory usage drastically.

 So let's go the next step. If there is an agreed on standard for API
 calls an application vendor (my imaginary purchasing system again...) can
 add the EDI function calls to my software and sell the package. My
 customer decides which EDI software company they like (maybe a little ol'
 cajun boy) and purchases the API modules. Bang, they have an EDI enabled
 application. Or perhaps I want to save my customers the trouble of
 looking for EDI modules, so I enter into a contract with my EDI vendor
 of choice to supply the modules. Either route is possible because my
 software is not locked into using only one set of EDI modules. As well
 I can offer the EDI functionality cheaper because I'm not buying a user
 interface I don't need. This is what all the BS about Open Systems is
 about.

 This makes it easier to change systems to integrate EDI, which may act
 as a catalyst to make it happen. It does, unfortunately, put an
 additional burden on the EDI vendor (who must develop the API modules).
 But the EDI vendor also benefits- it increases your potential market by
 allowing application vendors to 'add' EDI functionality with a minimum
 of effort. The EDI enabled package would be much more functional than
 any I've heard of (such as the EDI interface on Walker Interactive
 Systems accounting package- which just creates a file to pass to
 Sterling's mainframe EDI software). It would also support real time EDI,
 relatively easily.

 Regards, Bill Laidley
 EDI Expert Team
 BC Systems Corp. Vancouver (604) 660-9705
Comments: Gated by NETNEWS@AUVM.AMERICAN.EDU