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

Deno Deployと組み合わせるのに Upstashをおすすめしたい

Deno Deployと組み合わせるのに Upstashをおすすめしたい

Deno Deployと組み合わせるのに Upstashをおすすめしたい

虎の穴ラボ株式会社

August 31, 2022
Tweet

More Decks by 虎の穴ラボ株式会社

Other Decks in Technology

Transcript

  1. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    2022/08/24

    toranoana.deno #8 


    虎の穴ラボ

    奥谷 一陽

    Deno Deployと組み合わせるのに

    upstashをおすすめしたい


    View full-size slide

  2. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    自己紹介

    奥谷 一陽

    所属:虎の穴ラボ株式会社

    担当:とらコインSHOPなど新規事業系の開発

    興味:TypeScript、Deno

    おすすめコンテンツ:

      『プラネテス』

      『暴太郎戦隊ドンブラザーズ』


    Twitter:@okutann88


    View full-size slide

  3. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    Deno Deploy どのくらい使っ
    てますか?


    View full-size slide

  4. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    Deno Deploy と組み合わせる前提で、

    オススメSaaSを紹介したい


    View full-size slide

  5. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    upstash









    参考:https://upstash.com/


    View full-size slide

  6. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    upstash

    - カルフォルニアの Upstash, Inc. が運営するSaaS

    - Redis Kafka qStashを提供

    - キーワード:グローバル 低レイテンシ 上限付きの従量課金


    View full-size slide

  7. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    upstash の Redis

    - 無料プラン:10K コマンド/日

    - 有料プラン:0.2 $/100Kコマンド、月間最大 $120 まで

    - 公式が、deno.land/x にモジュールを公開済み

    https://deno.land/x/[email protected]
    - Redisと銘打つものの、内部でfetchが使用されたhttpリクエストを使用

    「Redisっぽく動く」 「Redis互換の」ぐらいの感触


    View full-size slide

  8. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    upstash の Redis の使用例

    import { Application, Router, Context } from "https://deno.land/x/oak/mod.ts";
    import { Redis } from "https://deno.land/x/upstash_redis/mod.ts";
    const redis = new Redis({
    url: Deno.env.get("UPSTASH_URL"),
    token: Deno.env.get("UPSTASH_TOKEN"),
    });
    const router = new Router();
    router.get("/", async (context: Context) => {
    const count = await redis.get("count");
    context.response.body = count;
    });
    router.post("/update", async (context: Context) => {
    await redis.incr("count");
    context.response.body = "updated";
    });
    const app = new Application();
    app.use(router.routes());
    app.use(router.allowedMethods());
    await app.listen({ port: 8080 });

    View full-size slide

  9. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    upstash の Redis で実際にやりたいのは?

    - キャッシュの仕組みが有ったときに、Webサービスで扱いたいのは

    「セッション」では無いだろうか(偏見かもしれません)

    - oak_session モジュール + upstash_redis モジュール は組み合わせ可能?

    => できる ただし...、 オプションが必須


    View full-size slide

  10. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    upstash の Redis を oak_session で使う

    import { Application, Context, Router } from
    "https://deno.land/x/oak/mod.ts";
    import { RedisStore, Session } from
    "https://deno.land/x/oak_sessions/mod.ts";
    import { Redis } from "https://deno.land/x/upstash_redis/mod.ts";
    const redis = new Redis({
    url: Deno.env.get("UPSTASH_URL")!,
    token: Deno.env.get("UPSTASH_TOKEN")!,
    automaticDeserialization: false, // <== ポイント
    });
    const router = new Router();
    router.get("/", async (context: Context) => {
    const name = await context.state.session.get("name");
    context.response.body = `




    ${!name ? "" : "name=" + name}



    submit



    `;
    });
    router.post("/", async (context: Context) => {
    const form = await context.request.body({ type: "form" }).value;
    const name = form.get("name");
    if (!!name) context.state.session.set("name", name);
    context.response.redirect("/");
    });
    type AppState = {
    session: Session;
    };
    const app = new Application();
    const store = new RedisStore(redis);
    app.use(Session.initMiddleware(store));
    app.use(router.routes());
    app.use(router.allowedMethods());
    await app.listen({ port: 8080 });

    upstash_redisは、デフォルトで、jsonの自動デシリアライズが
    ONになっているので この機能を停止させる

    デシリアライズは、oak_session に任せる!


    View full-size slide

  11. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    qStash ?

    - upstashの独自サービス

    - サーバーレス、エッジランタイム向け、HTTPベースメッセージング/

    スケジューリングソリューション

    - 無料プラン:50リクエスト/日

    - 有料プラン:50Kリクエスト/日 0.4 $/1Kリクエスト 月間最大 $450 

    - 最大のポイント Deno Deploy をスケジュール実行できる

    => さらに、upstash公式が deno deploy をサポート


    View full-size slide

  12. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    qStash の deno deploy サポート


    View full-size slide

  13. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    Deno Deployで qStash 使ってみる 

    以下の内容を実装する

    - qStashから1分に1回 Deno Deploy に置いたアプリを呼び出す

    - 呼び出しに対応して upstash Redisに保管した値をカウントする

    - ブラウザからアクセスし値を参照する


    View full-size slide

  14. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    Deno Deployで qStash 使ってみる 

    ポイント

    - 公式が、deno.land/x にモジュールを公開済み

    - https://deno.land/x/[email protected]
    - qStashからのリクエストであることを upstash_qstash モジュールを

    使い検証すること


    View full-size slide

  15. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    Deno Deploy で qStash を使う実装例

    import { Application, Router, Context } from
    "https://deno.land/x/oak/mod.ts";
    import { Redis } from
    "https://deno.land/x/upstash_redis/mod.ts";
    import { Receiver } from
    "https://deno.land/x/upstash_qstash/mod.ts";
    const redis = new Redis({
    url: Deno.env.get("UPSTASH_URL"),
    token: Deno.env.get("UPSTASH_TOKEN"),
    })
    const receiver = new Receiver({
    currentSigningKey:
    Deno.env.get("QSTASH_CURRENT_SIGNING_KEY")!,
    nextSigningKey:
    Deno.env.get("QSTASH_NEXT_SIGNING_KEY")!,
    });
    const router = new Router();
    router.get("/", async(context:Context) => {
    const count = await redis.get("count");
    context.response.body = count;
    });

    router.post("/update", async(context:Context) => {
    const isValid = await receiver.verify({ // <== ポイント
    signature: context.request.headers.get("Upstash-Signature")!,
    body: await context.request.body({ type: "text" }).value,
    }).catch((err: Error) => {
    console.error(err);
    return false;
    });
    if (!isValid) {
    return new Response("Invalid signature", { status: 401 });
    }
    await redis.incr("count");
    return new Response("OK", { status: 200 });
    });
    const app = new Application();
    app.use(router.routes());
    app.use(router.allowedMethods());
    await app.listen({ port: 8080 });

    View full-size slide

  16. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    現在動作中です。

    一分に一回カウントアップされます。
    https://late-otter-59.deno.dev/



    View full-size slide

  17. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    まとめ

    - Deno Deployの有効活用のため、upstashの組み合わせオススメ

    - 出来ることが、大きく広がる

    - Deno Deploy 起点のフルサーバーレスなサービスを開発できる可能性

    例えば?


    View full-size slide

  18. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    Deno Deploy 起点フルサーバーレス サービス インフラ 構想


    deno deploy
    ・APIサーバー
    ・DB管理
    ・ストレージ
    キャッシュ呼び出し
    Redis
    qStash
    バッチ処理呼び出し
    フロントサーバー

    View full-size slide

  19. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    Deno Deploy 起点フルサーバーレス サービス インフラ 構想

    deno deploy
    フロントサーバー
    ・APIサーバー
    ・DB管理
    ・ストレージ
    キャッシュ呼び出し
    Redis qStash
    バッチ処理呼び出し
    deno deploy
    +      +
    bunny cdn ...
    API呼び出し

    View full-size slide

  20. Copyright (C) 2021 Toranoana Inc. All Rights Reserved.
    ありがとうございました


    View full-size slide