Amazon API Gateway SDK for Java を触ってみた

毎度お馴染み流浪の動かしてみた & C 芸人の Fujimura です。

Amazon API Gateway Swagger Importer を触っていたら、内部で Amazon API Gateway SDK for Java が使われていることに気づいたため、importer を参考にしながら、SDK を触ってみることにしました。

インストール

Amazon API Gateway Swagger ImporterでAPIを一発で定義する | Developers.IO を参考にしてください。

触ってみる

importer とは逆に SDK の getter から API Gateway の情報を export する class を適当に書いて、pom.xml の Main をこちらにするように変更しておきます。

package com.amazonaws.service.apigateway.exporter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;

import com.amazonaws.service.apigateway.importer.ApiImporterMain;
import com.amazonaws.service.apigateway.importer.config.ApiImporterModule;
import com.amazonaws.service.apigateway.importer.config.AwsConfig;
import com.amazonaws.service.apigateway.importer.impl.ApiGatewaySwaggerFileImporter;
import com.amazonaws.service.apigateway.importer.impl.sdk.ApiGatewaySdkSwaggerApiImporter;
import com.amazonaws.services.apigateway.model.ApiGateway;
import com.amazonaws.services.apigateway.model.Integration;
import com.amazonaws.services.apigateway.model.Method;
import com.amazonaws.services.apigateway.model.Resource;
import com.amazonaws.services.apigateway.model.RestApi;
import com.google.inject.Guice;
import com.google.inject.Injector;

public class ApiExporterMain {

    private static final Log LOG = LogFactory.getLog(ApiExporterMain.class);

    static public void main(String[] args) {
        bootstrap();
        ApiExporterMain main = new ApiExporterMain();
        main.execute();
    }

    static void bootstrap() {
        Logger root = Logger.getRootLogger();
        root.setLevel(Level.INFO);
        root.addAppender(new ConsoleAppender(new PatternLayout("%d %p - %m%n")));
    }

    public void execute() {
        AwsConfig config = new AwsConfig("default");
        try {
            config.load();
        } catch (Throwable t) {
            LOG.error("Could not load AWS configuration. Please run 'aws configure'");
            System.exit(1);
        }

        try {
            Injector injector = Guice.createInjector(new ApiImporterModule(config));
            ApiGatewaySwaggerFileImporter importer = injector.getInstance(ApiGatewaySwaggerFileImporter.class);
            // client と apiGateway はそれぞれ private であるが、今回は直接参照したいため public に変更しておく。
            ApiGateway apiGateway = ((ApiGatewaySdkSwaggerApiImporter) (importer.client)).apiGateway;

            // 適当に取得できる情報を出力してみる。
            java.util.List<RestApi> restApis = apiGateway.getRestApis().getItem();
            for (RestApi restApi : restApis) {
                LOG.info("[" + restApi.getId() + "] " + restApi.getName());
                java.util.List<Resource> resources = restApi.getResources().getItem();
                for (Resource resource : resources) {
                    LOG.info("  [" + resource.getId() + "] " + resource.getPath());
                    java.util.Map<String, Method> methods = resource.getResourceMethods();
                    for (String key : methods.keySet()) {
                        Method method = methods.get(key);
                        LOG.info("    [" + key + "]");
                        LOG.info("      AuthorizationType : " + method.getAuthorizationType());
                        LOG.info("      ApiKeyRequired : " + method.getApiKeyRequired());
                        try {
                            Integration integration = method.getMethodIntegration();
                            LOG.info("      Integration : " + integration);
                            java.util.Map<String, String> requestParameters = integration.getRequestParameters();
                            if (requestParameters != null) {
                                LOG.info("        Parameters : ");
                                for (String key2 : requestParameters.keySet()) {
                                    LOG.info("          " + key2 + " : " + requestParameters.get(key2));
                                }
                            }
                            java.util.Map<String, String> requestTemplates = integration.getRequestTemplates();
                            if (requestTemplates != null) {
                                LOG.info("        Templates : ");
                                for (String key2 : requestTemplates.keySet()) {
                                    LOG.info("          " + key2 + " : " + requestTemplates.get(key2));
                                }
                            }
                        } catch (UnsupportedOperationException e) {
                        }
                    }
                }
            }
        } catch (Throwable t) {
            LOG.error("Error exporting API from Swagger", t);
            System.exit(1);
        }
    }
}

あらかじめ importer のサンプルにある tst/resources/large.json を import しておいた結果を export してみます。

$ ./aws-api-export.sh 
2015-10-08 11:59:04,912 INFO - [XXXXXXXXXX] Uber API v2
2015-10-08 11:59:05,191 INFO -   [AAAAAA] /v1/25
2015-10-08 11:59:05,194 INFO -     [GET]
2015-10-08 11:59:05,422 INFO -       AuthorizationType : NONE
2015-10-08 11:59:05,422 INFO -       ApiKeyRequired : false
2015-10-08 11:59:05,422 INFO -   [BBBBBB] /v1/7
2015-10-08 11:59:05,422 INFO -     [GET]
2015-10-08 11:59:05,629 INFO -       AuthorizationType : NONE
2015-10-08 11:59:05,629 INFO -       ApiKeyRequired : false
2015-10-08 11:59:05,629 INFO -   [CCCCCC] /v1/16
2015-10-08 11:59:05,629 INFO -     [GET]
2015-10-08 11:59:05,834 INFO -       AuthorizationType : NONE
2015-10-08 11:59:05,834 INFO -       ApiKeyRequired : false
2015-10-08 11:59:05,835 INFO -   [DDDDDD] /v1/9
2015-10-08 11:59:05,835 INFO -     [GET]
2015-10-08 11:59:06,035 INFO -       AuthorizationType : NONE
2015-10-08 11:59:06,035 INFO -       ApiKeyRequired : false
2015-10-08 11:59:06,035 INFO -   [EEEEEE] /v1/estimates/price
2015-10-08 11:59:06,035 INFO -     [DELETE]
2015-10-08 11:59:06,246 INFO -       AuthorizationType : NONE
2015-10-08 11:59:06,246 INFO -       ApiKeyRequired : false
2015-10-08 11:59:06,246 INFO -     [GET]
2015-10-08 11:59:06,490 INFO -       AuthorizationType : NONE
2015-10-08 11:59:06,491 INFO -       ApiKeyRequired : false
2015-10-08 11:59:06,491 INFO -     [OPTIONS]
2015-10-08 11:59:06,704 INFO -       AuthorizationType : NONE
2015-10-08 11:59:06,704 INFO -       ApiKeyRequired : false
2015-10-08 11:59:06,704 INFO -     [PUT]
2015-10-08 11:59:06,916 INFO -       AuthorizationType : NONE
2015-10-08 11:59:06,916 INFO -       ApiKeyRequired : false
2015-10-08 11:59:06,916 INFO -     [PATCH]
2015-10-08 11:59:07,118 INFO -       AuthorizationType : NONE
2015-10-08 11:59:07,118 INFO -       ApiKeyRequired : false
    :
    :

Integration が存在する API だと以下のような出力となります。

2015-10-08 11:59:11,207 INFO -   [xxxxxx] /hoge
2015-10-08 11:59:11,207 INFO -     [GET]
2015-10-08 11:59:11,420 INFO -       AuthorizationType : NONE
2015-10-08 11:59:11,420 INFO -       ApiKeyRequired : false
2015-10-08 11:59:11,423 INFO -       Integration : /restapis/XXXXXXXXXX/resources/xxxxxx/methods/GET/integration
2015-10-08 11:59:11,424 INFO -         Templates : 
2015-10-08 11:59:11,424 INFO -           application/json : {
  "foo": "$input.params('foo')"
}

まとめ

Amazon API Gateway SDK for Java を使用して、管理コンソールから設定した API Gateway の情報を出力してみました。標準の AWS SDK に同梱されるようになれば、もっと使いやすくなるものと思われます。