Search This Blog

Tuesday, 14 May 2013

Why to use Javascript-Policy over XML-Policy?

I believe that doing Policy-Steps with Javascript has several advantages:

1. You can read the code easier
2. time saving because of the number of reduced steps
3. possibility to use shared libs

See here a comparison what I mean:
1. Extract the given number from path /method/1234 => will set path.uri to 1234
OR
var IDfromPath=context.getVariable("proxy.pathsuffix").split("/").pop();
context.setVariable("path.uri",IDfromPath);


2. Difference on a service-callout - extracts the ObjectID from a callout and save it to variable "myID"
3 Steps needed: Instead of:
var ex1 = httpClient.get("http://www.someendpoint.com?some=value");
ex1.waitForComplete(); 
var result=JSON.stringify(ex1.getResponse().content);
context.setVariable("myID",result["objectID"]);
I found several examples for this - you know what I mean :-)

Shared javascripts-libs in flows

If you are doing a lot of validations, transformations or response-parsing you will very fast recognize that you need sometimes the same code on different routes or steps.

How about using shared javascript libaries?

Just create a javascript file with some functions like following and save it to a javascript file "sharedlib":

"sharedlib":
// sets request parameters
function setrequest(){
    request.method = 'GET';
    request.headers['Content-Type'] = 'text/html';
    request.body = "";
}

// sets the query param "fun" to given argument
function hello(message){
    request.queryParams["fun"]=message;
}


and include it in your javascript step like shown below and you are able to use this function in your normal javascript file.

"normaljsscript":
// some things you do here and then
setrequest();
hello("world");


I found no documentation about "IncludeURL" - thats a way to use it.

Wednesday, 8 May 2013

Proxy Editor Shortcuts

HOLD STRG + SHIFT and then use

cursor left - to toggle left column / Navigator
cursor right - to toggle right column / Property-Inspector
cursor up - to toggle flow view
cursor down - to toggle state bar

if you toggle off all options you have a very big code window
-> this is often useful to know on long code lines !

UNDO/REDO in code-windows
useful to know !!!

STRG Z undo
STRG Y redo

Undo is possible for 40 Steps backwards.
Each step is everything you do without stopping writing - with a handsoff time around 1/2 second.

so writing

hello
{now wainting - then adding world}
hello world
will be two steps !

writing "hello world" together without stop writing is one step!

! Pasting code frome elsewhere is also just one step !





Tuesday, 7 May 2013

Debugging techniques

To get the result you want - on request or response side it is useful to see some values.


TRACETOOL
When you are in the Api-Proxy-Editor you are able to start the "Trace"-Tool.
Within the Trace-Tool you can press the green "Listen"-Button.
Start your request with a client of your choose.
(
I like the chrome addon "http dev client" - https://chrome.google.com/webstore/detail/dev-http-client/aejoelaoggembcahagimdiliamlcdmfm?hl=de

But you can also use the apigee-console from within the Trace-Tool

or sometimes I just use curl for simple or very complicated requests [putting the content of a request in a local file]
)

After your request has finished you can inspect all steps which have run - sometimes it is important to know if a step has run or not! (we will see later in my post about flows....)

If you click on a step you see always this step and the step before and have the possibilty so look at headers, content and - if defined - variables.

The content will be cut after line 17.....so you are not able to see more content for a step.

Tip1: If you put your content in a variable you can see it all!
Tip2: small values or strings I put for debugging into a header variable - so I can see very fast what I want to know

Problem with Tracetool:
sometimes the content or queryparams are not displayed correct!!! I know apigee works on, but till it is ready we have two ways to skin the cat.

Tip1: Under the green "Listen"-Button is the "Download Data"-Button - you can download it and inspect it - hard to read, but full with information and give you a feeling how apigee works inside. I only use it, when I find no other way.

Tip2: use requestb.in/‎ as target-endpoint
It doesn't matter which kind of request you send to there.
They are in beta-state and have some problems with binary data and some chars - when your current bin shows you an error then just create a new bin and look at your data you sent or at the queryparams....
Bin's will be removed after 48 hours.....so don't care

Tip: requestb.in don't like content within GET request's - you will get a bad request error!


SETTING VARIABLES WITH JAVASCRIPT

create a NEW-NEW Script - Javascript, give it a name and set your vars:

context.setVariable("importantthing","test123"); // for variable
context.setVariable("mycontent",request.body); // for content-look-up in a variable
request.headers['Newtest']="something"; // for values in the header

create then a javaascript policy with NEW Policy - Javascript and choose at Dropdown "Scriptfile" your created javascript.

This step should be in the flow you want to inspect. (Drag-Drop it within the flow or pull it from the left side - deleting with x within the flow only removes from flow)

Start Trace-Mode and your request and enjoy to see what you want!













Useable Javascript Variables - all what you need !

On my way to find out how to manipulate flows and request attributes with javascipt I found out that there are some variables I can use and others are not useable - not documented in this way!

This is a reference on what you can use...


First have a look at the variable reference and tell me if you understand it....and have always a look at the permission column - this is really important!
http://apigee.com/docs/enterprise/content/predefined-variables

As you can see most variables are read-only and some are writable.

We start with "request.body" - can you find it?

Ah - sorry - look here for manipulating with javascript:

http://apigee.com/docs/enterprise/content/scripting-api-flow

Found it? No? Try here:

http://apigee.com/docs/enterprise/content/policies/add-scripting-features-to-your-API-using-JavaScript

or here looks interesting with more variables:

http://apigee.com/docs/api-platform/content/api-proxy-configuration-reference

and last hope is perhaps here:

http://apigee.com/docs/enterprise/content/apigee-javascript-object-model


A lot of reference - and believe me, because I tried the most - useless !

Have a look at this - here we find "request.body" - I will explain later what we need to know about this.
http://apigee.com/docs/enterprise/api/apigee-javascript-object-model


Enough! If you can't win - confuse ! Forget everything....


Use this on a request flow:   e.g. proxyendpoint/?test=123

QUERY-PARAMETER
var myvar = request.queryParams.test;  // myvar=123 - get a query parameter
request.queryParams["whatever"]="nice"; // set a queryparameter

HEADER
request.headers['Content-Type'] = 'application/xml'; // set Content-Type
request.headers['Content-Type'] = 'application/json'; // set Content-Type
request.headers['Content-Type'] = 'text/html'; // set Content-Type
request.headers['Newtest']="something"; // set Header-Var - good for debugging !!!

REQUEST-METHOD
request.method = 'GET';      // set request-method - use it to manipulate incoming requests-methods
request.method = 'POST';    // set request-method - use it to manipulate incoming requests-methods
request.method = 'PUT';     // set request-method - use it to manipulate incoming requests-methods
request.method = 'DELETE'; // set request-method - use it to manipulate incoming requests-methods

BODY / PAYLOAD / CONTENT
var oldcontent=request.body.asJSON; // get content as JSON ...if JSON
var oldcontent=request.body.asXML; // get content as XML...if XML

request.body = myrequest;          //    set a new body of reqest aka message aka payload


VARIABLES
(with context you can use it on request or response)
var newvar=context.getVariable("path.uri"); // get variables from variable reference(first link on this page) or variables exctracted from ExtractVariables-Policy!

context.setVariable("target.url",newurl); // to dynamically set a target-endpoint - can be with queryparams

context.setVariable("importantthing","test123"); // with setVariable you can also set own Variables and fetch them in later steps !!! Important !

important variables in combination with set/getVariable
target.url => target endpoint url - could be with queryparams on set or get
proxy.pathsuffix => the path after the basepath - Read-ONLY !!!


Use this on a response flow:

BODY / PAYLOAD / CONTENT
var responsecontent=response.content.asJSON; // if response is JSON - get the response
var responsecontent=response.content.asXML; // if response is XML - get the response
// do something with the response -> I will write another post for easy manipulation
response.content=JSON.stringify(data); // data is a javascript-object -> result is JSON

HEADER
response.headers['Content-Type']='application/json'; // set new content-type

some more will follow....most times nearly the same like request.....


If you found something important I missed - please test it first and then write a comment!


XML2JSON with javascript

This post is more or less a code snippet how to convert a XML-Content into JSON with javascript.

I had a problem with a very big XML-Entity and got an error
"errorcode":"steps.xml2json.ExecutionFailed"
-> this is my solution with a javascript-policy !

Here you can see it for the request flow. Change all "request"-vars to "response" and you are ready for the response flow. 

As you can see https://gist.github.com/olegp/642667 in comments section I had to modify it a little bit, because CDATA-Tags where not parsed correct - E4X has some common problems with CDATA and I was happy to found a working solution.
-> https://developer.mozilla.org/de/docs/E4X/Processing_XML_with_E4X
...For backwards compatibility, E4X defaults to ignoring comments and CDATA sections...

Tip: If you want to modify the result look at the ignore list and play around => ["type", "space", "xmlns", "html"]

// found here https://gist.github.com/olegp/642667
function E4XtoJSON(xml, ignored) {
  var r, children = xml.*, attributes = xml.@*, length = children.length();
  if(length == 0) {
    r = xml.toString();
  } else if(length == 1) {
    var text = xml.toString();
    if(text) {
      r = text;
    }
  }
  if(r == undefined) { 
    r = {};
    for each (var child in children) {
     var name = child.localName();
     var json = E4XtoJSON(child, ignored);
     var value = r[name];
     if(value) {
       if(value.length) {
         value.push(json);
       } else {
         r[name] = [value, json]
       }
     } else {
       r[name] = json;
     }
    }
  }
  if(attributes.length()) {
    var a = {}, c = 0;
    for each (var attribute in attributes) {
      var name = attribute.localName();
      if(ignored && ignored.indexOf(name) == -1) {
        a["_" + name] = attribute.toString();
        c ++;
      }
    }
    if(c) {
      if(r) a._ = r;
      return a;
    }
  }

  return r;
};

var oldcontent=request.body.asXML;
var newcontent=JSON.stringify(E4XtoJSON(oldcontent, ["type", "space", "xmlns", "html"]), null, '  ');

request.headers['Content-Type'] = 'application/json';
request.body = newcontent;

Why I write about apigee?

First of all - I have no relation to apigee and just using the free plan.

I will write how to manage things and how to solve api-needs you could have and maybe you can save many hours or days or even month to do it by your own.


Everything you need is to get a free accout here: http://apigee.com/about/ (Enterprise)

Start looking this yt-video from Greg Brail to understand what a big pleasure apigee's api gives to you.


In a way I am a apigee beginner with a lot of time pressure to solve a project. More than a year ago I saw a new addon on heroku.com and played a little bit with apigee-console. In a way it was boring so I dropped it very fast and forgot it.

About 8 weeks ago I got a nice project with a requirement to connect one app with several api's (and in future more api's) and googled around and found apigee again. (and remembered my boring time a year ago)

Looking two days at the documentation I was very depressed, because I was not able to understand how to use apigee. Terrible!

Now - about 4 weeks later - I know more and I think I am able to convert nearly every api to what I want! Amazing!

I wanted to start writing this blog with the finished project, but perhaps it's a good idea to do it now. And you can following my learning curve.....and I have to finish the project in the next 3 weeks.

First I will show you some basic tricks and then I plan to do a real world project with you -> to convert a complete soap-xml-rpc api into a json rest api !!!