Upgrade to Pro — share decks privately, control downloads, hide ads and more …

FaaS上のコードをもっとシンプルに書くためのトランスパイラ / Serverless Meetup Tokyo #13

FaaS上のコードをもっとシンプルに書くためのトランスパイラ / Serverless Meetup Tokyo #13

Serverless Meetup Tokyo #13での資料です
https://serverless.connpass.com/event/138983/

Kosaku Kimura

July 30, 2019
Tweet

More Decks by Kosaku Kimura

Other Decks in Programming

Transcript

  1. FaaS上のコードをもっとシンプルに
    書くためのトランスパイラ
    Kosaku Kimura, FUJITSU LABORATORIES LTD.
    [email protected]
    Copyright 2019 FUJITSU LABORATORIES LTD.
    0
    Serverless Meetup Tokyo #13
    2019年07月30日 @ 株式会社Speee

    View Slide

  2. 自己紹介
    Kosaku Kimura(木村 功作)
    株式会社 富士通研究所で
    ソフトウェア開発効率化・自動化の研究開発を行っています
    https://www.researchgate.net/profile/Kosaku_Kimura
    Copyright 2019 FUJITSU LABORATORIES LTD.
    kimusaku
    https://jawsdays2019.jaws-ug.jp/ http://www.apsec2018.org/
    1

    View Slide

  3. Copyright 2019 FUJITSU LABORATORIES LTD.
    トランスパイラって何?
    2

    View Slide

  4. トランスパイラ
    ソース(JavaScript)からソース(JavaScript)に変換するコンパイラ
     TypeScript: 型あり → 型なし
     Prettier: ぐちゃぐちゃ → きれい
     webpack: 大きい(読める) → 小さい(読めない)
     Babel: 新しい(まだない) → 古い(もうある)
    現代のJavaScript開発環境を支えている大事な技術
    Copyright 2019 FUJITSU LABORATORIES LTD.
    3

    View Slide

  5. 新しい → 古い はこんな感じ
    Copyright 2019 FUJITSU LABORATORIES LTD.
    4
    async function foo() {
    await bar();
    }
    var _asyncToGenerator = function (fn) {
    ...
    };
    var foo = _asyncToGenerator(function* () {
    yield bar();
    });
    https://babeljs.io/docs/en/babel-plugin-transform-async-to-generator

    View Slide

  6. シンプルなもの → ちゃんと動くもの が欲しい
     サーバレスだとできるだけコードを書きたくない
     けど全く書かないわけにはいかない
     ビジネスロジックは書かないといけない.あとAPI非同期呼び出しとか
     JavaScriptの非同期処理難しい
     コールバック, Promise, generator/yield, async/await・・・
     デプロイするものを軽くしたいから新しい依存関係を増やしたくない
     いい感じのシンプルさで書けて、実際の複雑な非同期処理に書き換えてくれ
    るようなトランスパイラって無いかなー
    Copyright 2019 FUJITSU LABORATORIES LTD.
    5

    View Slide

  7. あります(作りました)
    Escapin the TranspilerTM
    https://github.com/FujitsuLaboratories/escapin
    yarn global add escapin || npm install –g escapin
    特長
     Serverless Frameworkと連携
     DynamoDB Table, S3 Bucketが連想配列になる
     Swagger/OASで書かれたREST API呼び出しがJSONオブジェクト操作になる
     非同期処理のことを忘れられる
    Copyright 2019 FUJITSU LABORATORIES LTD.
    6

    View Slide

  8. Type Information
    Escapinのトランスパイル手順
    const items = {};
    ...
    items[id] = obj;
    ...
    ...
    await new Promise(
    (resolve, reject) => {
    Storage.put({
    name: "items",
    key: id,
    value: obj
    }, (err, res) =>{
    if (err) reject(err);
    else resolve(res);
    });
    ...
    AST Walker / テンプレート
    (Babel traverse/templateを使用)
    platform: a-cloud
    元のコード
    serverless.yml
    設定ファイル
    function function type
    Storage#put error-first-callback
    FaaSにデプロイする
    コード
    コールバック分解 詳細化 非同期化
    Copyright 2019 FUJITSU LABORATORIES LTD.
    関数型判別
    (TypeScript Compiler APIを使用)
    (c) 2019 Serverless, Inc.
    7

    View Slide

  9. コールバック分解
     中途半端な非同期をいったん同期側に全部倒す
    Copyright 2019 FUJITSU LABORATORIES LTD.
    func(arg, (err, data) => {
    if (err) {
    handleError(err);
    return;
    }
    doSomething(data);
    });
    try {
    const data = func(arg);
    doSomething(data);
    } catch (err) {
    handleError(err);
    }
    8

    View Slide

  10. 詳細化 – API
    Method
    Path
    GET POST PUT DELETE
    /items api.items api.items(body) api.items = body delete api.items
    /items/:id api.items[id] api.items[id](body) api.items[id] = body delete api.items[id]
    /items/:id
    with params
    api.items
    [id][params]
    api.items
    [id][params](body)
    api.items
    [id][params] = body
    delete api.items
    [id][params]
    Copyright 2019 FUJITSU LABORATORIES LTD.
    import api from 'https://path/to/swagger.yaml';
    const item = api.items[id];
    const item = request({
    'uri': `https://api.com/v1/items/${id}`,
    'method': 'get',
    'contentType': 'application/json',
    'headers': {
    'authorization': 'Basic ... '
    }
    });
     Swagger/OASを読み込んで型決め
    9

    View Slide

  11. Function Lambda
    export function foo(bar) {…} createFunction
    詳細化 – AWS
    Object DynamoDB S3
    export const obj: dynamodb|s3 = {} createTable createBucket
    obj[id] getItem getObject
    obj[id] = … putItem putObject
    delete obj[id] deleteItem deleteObject
    Copyright 2019 FUJITSU LABORATORIES LTD.
    10

    View Slide

  12. 関数型判別
    以下の4種類に緩く判別(TypeScript Compiler API使ってます)
    1. Asynchronous: Promiseを返すもの
     Axios.get等
    2. Error-first-callback: 第一引数がerrorオブジェクトなコールバックを引
    数に持つもの(Promisifyできるもの)
     Request, AWS SDK関連
    3. General-calback: Error-firstでないコールバックを引数に持つもの
     Arrayのmap, forEach等
    4. General: それ以外
    Copyright 2019 FUJITSU LABORATORIES LTD.
    11

    View Slide

  13. 非同期化
    Function Type
    DynamoDB#getItem error-first-callback
    Array#map general-callback
    … …
    元のコード 非同期化されたコード
    関数型
    Copyright 2019 FUJITSU LABORATORIES LTD.
    const data = new DynamoDB().getItem({
    TableName: 'csv',
    });
    const keys = data.Items.map(
    item => item.key.S);
    const _data
    = await new Promise((resolve, reject) => {
    new DynamoDB().getItem({
    TableName: 'csv', …
    }, (err, data) => {
    if (err) reject(err);
    else resolve(data);
    });
    });
    const keys = _data.Items.map(
    item => item.key.S);
    12

    View Slide

  14. 最後に
    https://github.com/FujitsuLaboratories/escapin
     面白そうと思った方はぜひ使ってみてください
     しばらくunstableが続きそうなのはご容赦
     欲しい機能、改善案、感想等、聞かせてください
    Copyright 2019 FUJITSU LABORATORIES LTD.
    13

    View Slide

  15. View Slide