1import * as Fly from "alchemy/Fly";
2import * as Effect from "effect/Effect";
3import * as Stream from "effect/Stream";
4import { HttpServerRequest } from "effect/http/HttpServerRequest";
5import * as HttpServerResponse from "effect/http/HttpServerResponse";
6import { API_PORT, Data } from "./shared.ts";
7
8/**
9 * HTTP Service that puts and gets an object on a Tigris bucket via
10 * the S3 API.
11 */
12export default class Api extends Fly.Service<Api>()(
13 "Api",
14 {
15 main: import.meta.url,
16 region: "iad",
17 port: API_PORT,
18 guest: { cpuKind: "shared", cpus: 1, memoryMb: 256 },
19 },
20 Effect.gen(function* () {
21 const putObject = yield* Fly.PutObject(Data);
22 const getObject = yield* Fly.GetObject(Data);
23
24 return {
25 fetch: Effect.gen(function* () {
26 const request = yield* HttpServerRequest;
27 const path = new URL(request.url, "http://service").pathname;
28 if (path === "/health") {
29 return yield* HttpServerResponse.json({ ok: true });
30 }
31 yield* putObject({
32 Key: "hello.txt",
33 Body: "hello-from-tigris",
34 ContentType: "text/plain",
35 }).pipe(Effect.orDie);
36 const obj = yield* getObject({ Key: "hello.txt" }).pipe(Effect.orDie);
37 const text =
38 obj.Body === undefined
39 ? ""
40 : yield* Stream.mkString(Stream.decodeText(obj.Body)).pipe(
41 Effect.orDie,
42 );
43 return yield* HttpServerResponse.json({
44 ok: text === "hello-from-tigris",
45 text,
46 });
47 }),
48 };
49 }).pipe(Effect.provide([Fly.PutObjectHttp, Fly.GetObjectHttp])),
50) {}