EGL and i

4 Posts tagged with the rest tag
8

Okay, I've written the first-generation RPG proxy program. Basically the proxy's job is to extract the request from the EGL Rich UI runtime and invoke the appropriate business logic.

It's a little more complex than that. If you're testing locally your request is automatically redirected to the local proxy that runs inside the workbench. The proxy calls your CGI service and your service extracts the data from the request. The request looks something like this:

{"bindingName":"PollService","method":"getPoll","params":[0]}

And you return data that looks something like this:

{"result" : { "name" : "Language Poll", "choices" : [{ "choice" : "RPG", "votes" : 87},{ "choice" : "EGL", "votes" : 33},{ "choice" : "PHP", "votes" : 2}]}}

Not too difficult. However, once you deploy to your host machine, things get a little more complex. The runtime no longer uses the proxy in the workbench, and instead it has to send to your proxy. Your proxy program then has to unbundle the request from the larger request, which now looks like this:

{"uri":"http:\/\/IRUIHOST\/cgi-bin\/POLLSVC2.PGM","queryParameters":{},"method":"POST","body":"{\"bindingName\":\"PollService\",\"method\":\"getPoll\",\"params\":[0]}","headers":{"EGLREST":"TRUE","egl_statefulsessionid":"JSESSIONID","Content-Type":"application\/json; charset=UTF-8"}}

A little more ugly, no? Not only that, you have to also buffer your reply into something just as complex. However, I managed to hide most of that complexity in a single program named EGLPRSCGI. I then have two programs, POLLCGI2 and CGIPROXY, each of which calls EGLCGIPRS to get the parameters from the client. Each then calls POLLSVC1, which is the actual business logic, and then formats the response as needed (CGIPROXY does a lot more formatting).

Eventually, CGIPROXY would have to recognize all the various requests and call the appropriate service program. But for now, you can get the project, and you can see the result on the SWICD website:

http://see-what-i-can-do.com/poll2.html

It's pretty slick, actually. :)

The project interchange file is on the project interchange discussion post.

8 Comments Permalink
0

Well, this has been an interesting little excursion. I really wanted to make sure that I tried to test the boundaries of the "Java-free" EGL/RPG architecture and as soon as I did, I ran into a little bump.

The problem is that you can't use a variable as the URL of the REST request. I don't understand the limitation and I haven't really asked about it yet, but the limitation is real for now. And because of that, you can't just pass your parameters as variables in the URL and then retrieve them with simple calls to QzhbCgiParse in your RPG-CGI program.

All is not lost. As it turns out, when you call a function in a REST service the parameters for the function are passed to the REST service as a JSON string. The JSON string is somewhat buried in the POST data and to make it even more challenging the data is in ASCII, but the parameters are more or less accessible, depending on how hard you're willing to look.

I'm going to take the time to write a simple procedure to extract the parameter string from the POST data. Then in order to make things simple I'll write a second procedure to treat the parameter string as a single string parameter (if that's not too confusing). It will assume that any REST function has only a single parameter of type string.

With that, I can then build comma delimited data in the Rich UI client and parse it in the RPG program using %scan. It's not quite as seamless or flexible as the magic Record-to-Data Structure conversion of EGL, but it will prove the point. Once that's done, though, I think it will be time for me to move to a true EGL Service implementation.

Anyway, that's what I'm working on. Hopefully I'll have it done in the next day or so. It's just a little bit of a speed bump.

Comments would be great. And if an IBMer happens along this and thinks I'm doing something completely bizarre, feel free to let me know... :)

0 Comments Permalink
0

Okay, this was a lot easier than I expected. I'm not saying it didn't requier a little research; the QzhbCgiParse API is not for the faint of heart. But a little research, a little careful reverse engineering, and I was able to create a program that responds to a Rich UI REST request. And it takes nine lines:

QzhbCgiParse( '-v Cust': 'CGII0100': cust: %size(cust):
              bytesRead : dsError);
if (bytesRead > 1);
  cust = %subst( cust: 1: bytesRead-1);
endif;

data = 'Content-Type: text/html' + CRLF + CRLF;
QtmhWrStout(data: %len(data): dsError);

data = '{"result" : "' + 'Name-' +
       %trim(cust) + '"}' + CRLF;
QtmhWrStout(data: %len(data): dsError);

return;


The simplicity of the code is rather impressive. The first line gets the data from the URL, the next three strip off the trailing LF that QzhbCgiParse insists on giving you. The next two lines send the header, the last two send the response formatted as a JSON string. That's all there is to it. There are obviously a couple of prototypes, and the ubiquitous error data structure that is familiar to anybody who codes API calls in RPG, but those can be /COPY'd in. The meat of the code is the eight lines above (nine counting the return).

The code in the test program is even simpler:

testService testService { @RESTBinding
  {baseURI = 
    "http://IRUIHOST/cgi-bin/RUIT1.PGM?Cust=77654"}};
call testService.getName() 
  returning to ts1listen
  onException ServiceLib.serviceExceptionHandler;


It's a standard REST call, except I change the baseRUI to pass the parameters. Now, I haven't gotten around to figuring out how to pass the parameter via the actual method call, but for this particular proof of concept I don't care about that. The point of this exercise is to prove that anything you can do with "traditional" EGL - that is, a web service written in EGL and deployed in an application server that calls an RPG program - can be done using nothing but the Powered by Apache server and standard RPG-CGI - that is, no Java, no WebSphere, nothing you wouldn't have to know for any other approach. You just have to learn the EGL Rich UI syntax.

Now, I wouldn't recommend this approach since if you can write EGL Rich UI you can write host-based EGL just as easily, but if you absolutely cannot run WebSphere or Tomcat, then this will allow you to still use EGL Rich UI.

Nifty, huh?

Let me clean up the example to something a little less trivial and I'll post this project, probably tomorrow sometime. As I noted at the beginning, I'm doing this solely in my free time and I used up most of that time tonight writing this blog post :).

0 Comments Permalink
0

See What i Can Do - V2R0

Posted by JoePluta Aug 30, 2009

Okay, I'm now in the pre-flight phase of version two. I'll leave V1 alone for the time being, although I may circle back to it later in order to investigate other pure client-side issues. But I want to get right to the core of what's important to EGl and i, calling business logic on the i. The purpose of V2 is to address the issue that EGL Rich UI requires WebSphere (or some other web application server) to run.

That's simply not the case. Rich UI handles both SOAP and REST service calls, which means that it talks to anything that does either of those. Most platforms can create SOAP services. The problem is that SOAP is over-engineered bloatware; the correct answer is to use REST.

Unfortunately, I don't have any examples of using pure RPG-CGI as either a SOAP service provider or a REST service provider. I could use the wizard provided with the standard i5/OS web administration tool to create a "Web Service Server" but that's still a SOAP service. I'm going to try a sidetrack to write my own code that will provide a simple REST response.

As always I'll be relying on groundwork done by others, in this case I'll probably be reviewing and probably liberally re-engineering code from Craig Pelkie and Scott Klement, as well as making use of Chris Laffra's service monitor. I'll need all the help I can get, because this is completely untraveled territory.

Wish me luck - I'll get back to you in a day or two.

0 Comments Permalink
Bottom Banner