[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: HTTPAPI How to do a POST



If you are on an old release (that's my guess as to why you'd get this error) then you may have to wrap the constants with %CHAR. i.e., do this:

myJSON = %Char(LeftBrace)
       + ' "email": "somebody@xxxxxxxxxxxxx"'
       + %char(Comma) + ' "givenName": "Fred"'
       + %char(Comma) + ' "surname": "Rubble" '
       + %char(RightBrace);


Does that help?

Otherwise, look to make sure you don't have two + symbols in a row (such as one at the end of a line, and then another at the start of a line).  That's a common mistake that results in this error -- though, the code that I provided did not make that mistake, so it might be the %CHAR thing, above.

-SK



On 8/29/2013 4:34 PM, Kevin Miller wrote:
The compiler is complaining  with "Operands are not compatible with the type of operator" for the LeftBrace, Comma, and RightBrace; Can you think of another way to concatenate these encoded characters? Thx for you help.

Kevin

myJSON = LeftBrace + ' "email": "somebody@xxxxxxxxxxxxx"'
              + Comma     + ' "givenName": "Fred"'
              + Comma     + ' "surname": "Rubble" '
              + RightBrace;
-----Original Message-----
From: ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx [mailto:ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of Scott Klement
Sent: Thursday, August 29, 2013 1:40 PM
To: HTTPAPI and FTPAPI Projects
Subject: Re: HTTPAPI How to do a POST

Kevin,

HTTPAPI does not provide a procedure that specifically saves the result to a string.  However, there's a routine called http_url_post_raw() that sends data as it arrives off the network to a callback routine.  The idea is to let you write your own custom "save data" procedure that can save the data anywhere you like.

People will often write a subprocedure that simply builds a string containing the response (instead of saving it to disk).  This is pretty easy to do in modern RPG, now that we have large string sizes and VARYING data values.  (In the old days, like V3Rx it was not so easy.)

There should be examples of this in the archives (or in the EXAMPLE members included with HTTPAPI)


On 8/29/2013 11:40 AM, Kevin Miller wrote:
Great info, thanks Scott! One more question, is there a way to tell httpAPI that I want it to call a procedure with the response, instead of going to a file.... like the http_url_post_xml procedure does? I'm trying to use http_url_post now. Should I be using a different procedure?

Kevin

-----Original Message-----
From: ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx [mailto:ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of Scott Klement
Sent: Tuesday, August 27, 2013 5:15 PM
To: HTTPAPI and FTPAPI Projects
Subject: Re: HTTPAPI How to do a POST

Kevin,

JSON data is only a character string.  HTTPAPI can send it in exactly the same manner as any other string.

However, a significant problem is that there are very many different EBCDIC encodings, and many of them have different code points ("hex values" in common parlance) for the [, ], { and } characters that are ubiquitous in JSON data.  One easy way to work around this is to define these special characters as Unicode (UCS-2) fields in RPG, and let RPG translate them on the fly.

Here's an example of defining these characters as UCS-2 constants:

D LeftBracket     C                   Const(%UCS2('['))
D RightBracket    C                   Const(%UCS2(']'))
D LeftBrace       C                   Const(%UCS2('{'))
D RightBrace      C                   Const(%UCS2('}'))
D Pound           C                   Const(%UCS2('#'))
D Exclamation     C                   Const(%UCS2('!'))
D Comma           C                   Const(%UCS2(','))
D Pipe            C                   Const(%UCS2('|'))

or, perhaps it'd be better to define these by their hex values (in case the source ends up compiled on different machines with different CCSIDs)

D LeftBracket     C                   U'005b'
D RightBracket    C                   U'005d'
D LeftBrace       C                   U'007b'
D RightBrace      C                   U'007d'
D Pound           C                   U'0023'
D Exclamation     C                   U'0021'
D Comma           C                   U'002c'
D Pipe            C                   U'007c'

Once you have that sorted out, you can create your JSON document just using regular RPG string concatenation (Provided, of course, that all of the chars you plan to use exist in EBCDIC -- but this is usually not an issue if your stuff is already in an IBM i database, since it's likely already encoded in EBCDIC.)

D myJSON          S          65535a   varying

    /free
       myJSON = LeftBrace + ' "email": "somebody@xxxxxxxxxxxxx"'
              + Comma     + ' "givenName": "Fred"'
              + Comma     + ' "surname": "Rubble" '
              + RightBrace;

If you find this method of building JSON data to be too difficult or cumbersome, then I do have an open source tool for generating/parsing JSON that might interest you, called YAJL:
http://www.scottklement.com/yajl/

Alternately, you could use Henrik Rutzou's PowerEXT, which is another good way.

But, if your JSON document is as simple as your example, it might be just as easy to create it with RPG's string manipulation, as shown above.

Once you have it in a string, you can send it to the HTTP server. Use HTTP_setCCSIDs to tell HTTPAPI to trasnlate it to UTF-8 (CCSID 1208), and then use HTTPAPI's http_post() routine to do the POST operation:

    http_setCCSIDs( 1208: 0 );

    // Also need code here to set up 'additional headers'

    rc = http_post( 'http://the-url-goes-here'
                  : %addr( myJSON : *data )
                  : %len( myJSON )
                  : '/ifs/path/to/result.json'
                  : HTTP_TIMEOUT
                  : HTTP_USERAGENT
                  : 'application/json' );
    if rc <> 1;
       // handle error
    endif;

In this example, the response from the server is saved to a file called 'result.json' in the '/ifs/path/to' directory of the Integrated File System (IFS).  There are other HTTPAPI routines that can be used to save it elsewhere if desired.

The remaining things you asked for are the 'Accept:' and 'Authorization:' headers.  This is a bit more complicated -- as these are features that folks don't often need to change.  HTTPAPI has the ability to interrupt it's processing at various points and call a procedure (which you will write) that will allow you to define a different behavior for HTTPAPI.  These 'points' are known as "exit points", and the procedure of yours that is run is known to HTTPAPI as
an "exit procedure".   So HTTPAPI will stop it's processing, call your
procedure, and then continue.  In this case, you want to define "additional HTTP headers" -- which is done with the HTTP_POINT_ADDL_HEADER exit point.

So, above, where I have a comment saying "set up additional headers", you'll need to add this code:

http_xproc( HTTP_POINT_ADDL_HEADER
             : %paddr(your-rpg-subprocedure-name) );

You can name your RPG subprocedure anything you like.  Perhaps you'd like to call it "add_headers" for example.  Then you'd code it like this:

http_xproc( HTTP_POINT_ADDL_HEADER
             : %paddr(add_headers) );

HTTPAPI expects your subprocedure to have a particular parameter list.
This should be coded at the bottom of your application (where subprocedures normally go) and would look similar to this:

P add_headers     B
D                 PI
D   headers                  32767a   varying
D CRLF            C                   x'0d25'
D token           s           1024a   varying
    /free
      // code to calculate 'token' should go here.

      headers = 'Accept: application/json' + CRLF
              + 'Authorization: OAuth oauth_token=' + token + CRLF;
    /end-free
P                 E

Note:  I strongly suspect that the 'Accept:' header is optional. You can omit it if you like -- if I'm right, it won't make any difference.  On the other hand, it's not hard to add, as shown above.

HTTPAPI does not have any routines for building OAuth tokens -- so how you calculate the token is left for you to figure out.

Hope that helps!


On 8/26/2013 4:00 PM, Kevin Miller wrote:
      With the following settings:


      HTTP/1.1
      Accept: application/json
      Content-Type: application/json
      Authorization: OAuth oauth_token={oauthToken}

      {
        "email": "somebody@xxxxxxxxxxxxx",
        "givenName": "Fred",
        "surname": "Rubble"
      }

      I need to set it up to use json data both to and from the external API,
      and pass in an email address, first and last name. I don't think I need
      a parser, as the data is very limited that I'm passing in and getting
      back. I also need to pass in an API Key as shown above in the
      Authorization line.


      Kevin


-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------
-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------

-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------
-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------


-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------