Node.jsでServerless Application Repositoryに公開されているアプリケーションを検索する

AWS re:invent 2018のワークショップ「Alexa, Ask Jarvis to Create a Serverless App for Me (SRV315) 」に参加していてずっと疑問だったのが、「Se […]

広告ここから
広告ここまで

目次

    AWS re:invent 2018のワークショップ「Alexa, Ask Jarvis to Create a Serverless App for Me (SRV315) 」に参加していてずっと疑問だったのが、「Serverless Application Repositoryのアプリってどうやって検索するの?」というところでした。

    いろいろ調べた結果「コンソールで使われているGET APIがそのまま叩けそうだ」ということに行き着いたのでざっとまとめました。

    注意

    2019/1/8時点の情報です。AWSが内部で利用しているAPIを勝手に使う形ですので、今後のアップデートによって動作しなくなる可能性があることをご了承ください。

    コード

    いきなりプロトタイプです。

    require('es6-promise').polyfill();
    require('isomorphic-fetch');
    
    class SARSearchUrlFactory {
      static init () {
        const url = 'https://shr32taah3.execute-api.us-east-1.amazonaws.com/Prod/applications/search'
        const queries = []
        return {
          setSearchQuery(query) {
            queries.push(`searchText=${query}`)
            return this
          },
          setPageSize(size = 10) {
            queries.push(`pageSize=${size}`)
            return this
          },
          setPageNumber(number = 0) {
            queries.push(`pageNumber=${number}`)
            return this
          },
          setCategory(category) {
            queries.push(`category=${category}`)
            return this
          },
          setRuntiime(runtime) {
            queries.push(`runtime=${runtime}`)
            return this
          },
          getUrl() {
            if (queries.length < 1) return url
            return `${url}?${queries.join('&')}`
          }
        }
      }
    }
    
    const builder = SARSearchUrlFactory.init()
    builder.setSearchQuery('alexa')
    builder.setPageSize(1)
    console.log(`URL: ${builder.getUrl()}`)
     
    fetch(builder.getUrl())
        .then(function(response) {
            if (response.status >= 400) {
                throw new Error("Bad response from server");
            }
            return response.json();
        })
        .then(function(stories) {
            console.log(stories);
        });

    実行すると、こうなります。

    $ node sar.js 
    URL: https://shr32taah3.execute-api.us-east-1.amazonaws.com/Prod/applications/search?searchText=alexa&pageSize=1
    
    { approximateResultCount: 24,
      applications: 
       [ { id: 'arn:aws:serverlessrepo:us-east-1:233054207705:applications/alexa-anagram',
           name: 'alexa-anagram',
           description: 'Alexa responds with the count and anagrams for a requested word',
           publisherAlias: 'evanchiu',
           homePageUrl: 'https://github.com/evanchiu/alexa-anagram',
           deploymentCount: 73,
           labels: [Array],
           requiredCapabilitiesForLatestVersion: [] } ] }

    簡単な解説

    ようはGETのAPIクエリを作ればOKということです。今回は検索に使うクエリのパターンが多くなりそうだったので、Factory Method化してあります。本来はTypeScriptで型をつけておきたいところですが、runtimeやcategoryあたりの型まで調べることになると大変そうだなと思ったのでお手軽方式にしています。

    アプリケーションの詳細情報まで取得する

    アプリケーションのIDさえわかれば、AWS SDKから他の情報を引っ張ることが可能です。

    const builder = SARSearchUrlFactory.init()
    builder.setSearchQuery('alexa')
    builder.setPageSize(1)
    console.log(builder.getUrl())
     
    fetch(builder.getUrl())
      .then((response) => {
          if (response.status >= 400) {
              throw new Error("Bad response from server");
          }
          return response.json();
      })
      .then((response) => {
        const application = response.applications[0]
        const serverlessapplicationrepository = new AWS.ServerlessApplicationRepository()
        const params = {
          ApplicationId: application.id
        };
        return serverlessapplicationrepository.getApplication(params).promise() 
      })
      .then(response => {
        console.log(response)
      });

    レスポンスはこうなります。

    { ApplicationId: 'arn:aws:serverlessrepo:us-east-1:233054207705:applications/alexa-anagram',
      Author: 'evanchiu',
      CreationTime: '2017-11-30T18:13:37.730Z',
      Description: 'Alexa responds with the count and anagrams for a requested word',
      HomePageUrl: 'https://github.com/evanchiu/alexa-anagram',
      Labels: [ 'alexa', 'nodejs', 'anagram' ],
      LicenseUrl: 'https://awsserverlessrepo-applications-eji6x7x4bodi.s3.amazonaws.com/233054207705/alexa-anagram/assets/license.txt?X-Amz-Security-Token=XXXXXXXXX',
      Name: 'alexa-anagram',
      ReadmeUrl: 'https://awsserverlessrepo-applications-eji6x7x4bodi.s3.amazonaws.com/233054207705/alexa-anagram/assets/readme.md?X-Amz-Security-Token=XXXXXXXXX',
      SpdxLicenseId: 'MIT',
      Version: 
       { ApplicationId: 'arn:aws:serverlessrepo:us-east-1:233054207705:applications/alexa-anagram',
         CreationTime: '2017-11-30T18:13:37.706Z',
         ParameterDefinitions: [],
         RequiredCapabilities: [],
         ResourcesSupported: true,
         SemanticVersion: '1.0.0',
         SourceCodeUrl: 'https://github.com/evanchiu/alexa-anagram',
         TemplateUrl: 'https://awsserverlessrepo-applications-eji6x7x4bodi.s3.amazonaws.com/233054207705/alexa-anagram/1.0.0/transformed-template.yaml?X-Amz-Security-Token=XXXXXXXXX' } }

    いくつかPreSignedURLが含まれていますので、使用する場合は直前にAPIを叩いて最新データを取得する様にした方がよさそうです。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark