Monday, August 18, 2014

Handling for CLASSIFICATION_FAILURE (404 Handling)

One of the production checklist items while setting up Apigee for production is handling a invalid API call.  The call typically results in CLASSIFICATION_FAILURE error.  This is a stackoverflow question related to issue.

Its always best to have a catch all URL in production environment of Apigee.  You can create brand new proxy with a base path  / . This proxy can have a single flow that returns the custom message using an assign message policy. This catch all proxy is like a custom 404 handler in web-servers.

Monday, June 16, 2014

stdout in Javascript Callout

Writing to console in Javascript callout is useful in some scenarios of debugging.  The print function can be used for writing to stdout.

print('Hello World From Javascript Callout');

would output the message to stdout.

stdout can be seen in trace when you click on the Javascript policy that logged to console.



Monday, June 9, 2014

Flow variables in URL of HTTPTargetConnection

HTTPTargetConnection with URL can be  used in two places as of now - service callout and target endpoint. Following are the configuration differences in both usages.

Service Callout
<HTTPTargetConnection>
    <URL>http://{backend_url}</URL>
</HTTPTargetConnection>

Target Endpoint
<HTTPTargetConnection>
   <URL>http://apigee.com/{backend_path}</URL>
</HTTPTargetConnection>

Details:

  • Protocol must be static in both cases it cannot be part of a flow variable used. The validation of requirement is done during deployment time.
  • Host (apigee.com in above example) must be static in case of target endpoint. This cannot be part of flow variable; making host part of the flow variable causes failure with error code 500 even though the validation during deployment succeeds.


Monday, June 2, 2014

Handling 404 backend response

In REST API interactions its common to obtain and handle 404 response. The behaviour is used to support create or update scenario for a resources. Check if the resource exists, if it does update it using PUT otherwise create it using POST verb.

404 response from backend is treated as an error in Apigee and such a response results in execution of the fault flow instead of the response flow. The method of dealing with such a scenario is to use the success.codes property of target endpoint properties. Following is an example configuration of target end point to deal with 404 as a success response.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TargetEndpoint name="billing">
    <HTTPTargetConnection>
        <LoadBalancer>
            <Algorithm>RoundRobin</Algorithm>
            <RetryEnabled>true</RetryEnabled>
            <MaxFailures>10</MaxFailures>
            <Server name="BillingTarget">
                <IsEnabled>true</IsEnabled>
            </Server>
        </LoadBalancer>
        <Path>/user/{userid}/bill/{bill_id}</Path>
        <Properties>
            <Property name="success.codes">1XX,2XX,3XX,404</Property>
        </Properties>
        <HealthMonitor>
            <IsEnabled>true</IsEnabled>
            <IntervalInSec>5</IntervalInSec>
            <TCPMonitor>
                <ConnectTimeoutInSec>10</ConnectTimeoutInSec>
                <Port>443</Port>
            </TCPMonitor>
        </HealthMonitor>
    </HTTPTargetConnection>
</TargetEndpoint>

The success codes property above ensures that default behaviour is retained in addition to treating 404 as a success code. This configuration will ensure response flow of the proxy will be executed in case of 404 response too. Appropriate action can be take in the response flow by checking the status code value.

Wednesday, May 14, 2014

Functionality Provided By Apigee

Following is a simple concise summary (which i like!!) on what Apigee provides by my colleague Michael Bissell on stack overflow.

----
http://stackoverflow.com/a/22901404

Where to put functionality in the flow is usually contextual but there are a few easy things to put in every proxy:
1) Key Management: Using Apigee to manage your API keys and mint your access tokens gives you a couple things; first line of defense for unauthorized apps and automatic analytics about what the developer is doing (getting a high error rate from one app? reach out to them and help them solve their problem proactively).
2) Basic Security Policies: Once you know the App is allowed to access your API there are some simple security policies that should be run on the Apigee layer. Payload enforcement (JSON and XML threat protection, regular expressions to block things like SQL injection or other invasive code). You can also set quotas based on the API Key (different developers getting different levels of access based on the products you associate with their keys). You also want to set spike arrests to keep your API traffic from overwhelming your target server.
3) Response Management: Make sure you strip out unnecessary response headers (cookies, server versions, etc) that aren't relevant to the API Contract. No need to tell your app developers about your target architecture, but it's sometimes hard to suppress those headers from application servers. You may also want rules to block unexpected responses from the target server (500 errors that may contain stack traces for example).
4) Caching: The ability to cache responses in Apigee drives a lot of the rest of "where to do it" questions. But being able to return a Cached response from Apigee can decrease your latency by hundreds of milliseconds improving your transactions per second and your developer/consumer satisfaction. The question now becomes how fine-grained you can get your cached response without having to go to the target server.
Beyond that it becomes "Where is it easiest and most efficient to do a task?" Things like JSON to XML, for example, are easy in Apigee, but they're easy in other platforms that may be running on your backend server, too.
----

Wednesday, May 7, 2014

Clean-up old revisions of API proxies from Apigee Org

The revisions of proxies tend to grow, specifically in an Apigee org used as development environment. Cleaning old un-deployed revisions not only de-clutters the UI but also eliminates unnecessary storage. At times speeds up deployment process too.

Following is a simple perl script I use to automatically clean up un-deployed versions of the proxy. The perl script use the resty command line client to clean up the revisions it found in the org.

#!/usr/bin/perl
use strict;
use JSON;
use Data::Dumper;

my @proxies=("apiproxy1","apiproxy2", "apiproxy3","apiproxy4");

$\ = "\n";
$user="username";
$passwd="password";

foreach my $p (@proxies) {
 print "Processing proxy: $p";
 my $res=`curl -s https://api.enterprise.apigee.com/v1/o/<orgname>/apis/$p -u $user:$passwd`;

 my $json=decode_json $res;
 my @revs=@{$json->{'revision'}};
 foreach my $rev (@revs) {
  print `curl -s -X DELETE https://api.enterprise.apigee.com/v1/o/<orgname>/apis/$p/revisions/$rev -u $user:$passwd`;
 }
}


Tuesday, April 1, 2014

JSON payload for a Fault

We need to generate a JSON output in case of fault. RaiseFault policy is appropriate for the same. Following is an example policy
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RaiseFault async="false" continueOnError="false" enabled="true" name="invalid_login">
    <FaultResponse>
        <Set>
            <Payload contentType="application/json" variablePrefix="%" variableSuffix="#">
                {
                    "error": "Incorrect login credentials",
                    "source": "API error"
                }
            </Payload>
            <StatusCode>400</StatusCode>
        </Set>
    </FaultResponse>
</RaiseFault>

Why this so different  - please note the variablePrefix, variableSuffix being present even though the content type is application/json and no variables are used. contentType attribute does not have the same impact as in AssignMessage policy. The presence of {} leads to the interpretation of the data between them as variable name. The variablePrefix and variableSuffix change solves the problem.