Help us understand the problem. What is going on with this article?

実サービスでAWS Lambda内でsqlite3を使った話

More than 3 years have passed since last update.

この記事は株式会社ネクスト(Lifull) Advent Calendar 2016の10日目です。

はじめに

株式会社ネクスト(2017年4月より新社名Lifull) HOME'Sのテックリードの冨田です。
HOME'SのiOS/Androidアプリ用のAPIの担当も担当しております。

社内でgolangが流行り始めているようですが、
AWS Lambdaがgolangを素では使えないのでネイティブアプリチームではnode.jsを利用しています。

システム構成

HOME'Sアプリの利用していたAPIはWEBサイトと共通のAPI基盤に同居しており、ネイティブアプリエンジニアは手を出しにくい環境でした。
昨年の冬頃から下記を目指しAPIのリニューアルを行い、今年の夏頃から本格的に運用し始めました。

  • ネイティブアプリエンジニアでもAPIを実装できリードタイムを減らす
  • 他チームとの影響範囲を減らし、リリース頻度を上げる
  • コストの見える化を行い、不要なものを減らし再投資する

リニューアル後のAPIはBFF(Backends for Frontends)にAmazon API Gateway + AWS Lambda(Node.js-v4.3.2)を利用しており、1画面を構成するのに必要なデータをまとめてネイティブアプリに返しています。

ネイティブアプリ => ネイティブアプリ用BFF => HOME'S共通のAPI

Amazon API Gateway + AWS Lambdaを選択した理由としては

  • セキュリティアップデートを行う時間をサービスの開発時間に当てることができる
  • プッシュ通知などで突発的な負荷があってもスケールしてくれる

というところでした

本題

ネイティブアプリでのみ利用しており、頻繁に更新しないマスタデータに関しては、
Lambdaのソースコードとして持っていたほうが速度的に速いので、
sqlite3のファイルを一緒にデプロイし利用しています。

環境

  • Node.js 4.3.2
  • npm
    • aws-sdk 2.6.3
    • sqlite3 3.1.8

Macでの環境構築については以前の記事をご覧ください

サンプルコード

実際のソースコードはお見せできないのでサンプルコードをご覧ください。

https://github.com/tomiyan/lambda-sqlite3-sample

事前にdbファイルを作成する部分。

'use strict';

var sqlite3 = require('sqlite3')
  ;

exports.exec = function (callback) {
  var db = new sqlite3.Database('data/test.db')
    , names = []
    ;

  names.push('JavaScript');
  names.push('Java');
  names.push('Go');
  names.push('Scala');
  names.push('Ruby');
  names.push('Python');
  names.push('Perl');
  names.push('PHP');

  db.serialize(function () {
    db.run('drop table if exists master');
    db.run('create table master (id integer primary key autoincrement, name text)');
    var stmt = db.prepare('insert into master (name) values (?)');

    names.forEach(function (name) {
      stmt.run(name);
    });
    stmt.finalize();
    db.each('select id, name from master', function (error, row) {
      console.log(row.id);
      console.log(row.name);
    });
  });
  db.close();
  callback();
}

DBからselectする部分。

'use strict';

var sqlite3 = require('sqlite3')
  ;

exports.exec = function (callback) {
  var db = new sqlite3.Database('data/test.db', sqlite3.OPEN_READONLY)
    ;
  db.each('select id, name from master', function (error, row) {
    console.log(row.id);
    console.log(row.name);
  });
  db.close(callback);
}

まとめ

DBファイルを一緒にデプロイしてあげれば、簡単に利用することができました。
頻繁に変更があるデータだと、その都度デプロイしなければなりませんが、
更新頻度が低いものであれば実用可能ではないでしょうか。

株式会社ネクスト(Lifull) Advent Calendar 2016の11日目の記事は先日弊社で開催したイベントで名司会だった国際事業部の@rechiba3さんです。

関連記事

tomiyan
最近はAPI Gateway、Lambda、k8sを主にやっています
http://tomiyan.net/
kurashicom
「北欧、暮らしの道具店」を運営するクラシコムのエンジニアチーム。
https://hokuohkurashi.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away