Skip to content

API Gateway

  1. Scaffold the following package structure inside the orchestrators workspace:

    • Directoryorchestrators
      • Directoryapi-gateway
        • Directorysrc
          • Directoryapi
            • Api.ts
          • Worker.ts
        • package.json
        • tsconfig.json
        • tsconfig.app.json
  2. Populate package.json based on the following pattern:

    {
    "name": "@project-name/api-gateway-orchestrator",
    "version": "0.0.0",
    "private": true,
    "dependencies": {
    "alchemy": "2.0.0-beta.36",
    "effect": "4.0.0-beta.63"
    }
    }
  3. Populate tsconfig.app.json based on the following pattern:

    {
    "extends": "../../tsconfig.base.json",
    "include": ["src/**/*.ts"],
    "references": [],
    "compilerOptions": {
    "outDir": "./tsbuild",
    "types": ["bun"]
    }
    }
  4. Populate tsconfig.json based on the following pattern:

    {
    "extends": "../../tsconfig.base.json",
    "files": [],
    "references": [{ "path": "./tsconfig.app.json" }]
    }
  5. Add package reference in tsconfig.json at repository root:

    {
    "extends": "./tsconfig.base.json",
    "files": [],
    "references": [
    {
    "path": "./orchestrators/api-gateway"
    }
    ]
    }
  6. Add package path alias in tsconfig.base.json at repository root:

    {
    "compilerOptions": {
    "paths": {
    "@skoreon/api-gateway-orchestrator/*": ["./orchestrators/api-gateway/*"]
    }
    }
    }
  7. Populate src/api/Api.ts based on the following pattern:

    import * as HttpApi from "effect/unstable/httpapi/HttpApi";
    export default class Api extends HttpApi.make("Api") {}
  8. Populate src/Worker.ts based on the following pattern:

    import Api from '@project-name/api-gateway-orchestrator/src/api/Api';
    import * as Cloudflare from 'alchemy/Cloudflare';
    import * as Effect from 'effect/Effect';
    import * as Layer from 'effect/Layer';
    import * as HttpRouter from 'effect/unstable/http/HttpRouter';
    import * as HttpServer from 'effect/unstable/http/HttpServer';
    import * as HttpApiBuilder from 'effect/unstable/httpapi/HttpApiBuilder';
    import * as HttpApiSwagger from 'effect/unstable/httpapi/HttpApiSwagger';
    export default class ApiGateway extends Cloudflare.Worker<ApiGateway>()(
    'ApiGateway',
    {
    main: import.meta.filename,
    observability: { enabled: true },
    },
    Effect.succeed({
    fetch: HttpApiBuilder.layer(Api, { openapiPath: '/openapi' }).pipe(
    Layer.provide(HttpApiSwagger.layer(Api, { path: '/swagger' })),
    Layer.provide(HttpServer.layerServices),
    HttpRouter.toHttpEffect,
    ),
    }),
    ) {}
  9. Add worker to deployment stack in alchemy.run.ts at repository root:

    // Existing imports...
    import ApiGateway from '@project-name/api-gateway-orchestrator/src/Worker';
    export default Alchemy.Stack(
    'ProjectName',
    {
    providers: Cloudflare.providers(),
    state: Cloudflare.state(),
    },
    Effect.gen(function* () {
    // Existing resources...
    const apiGateway = yield* ApiGateway;
    return {
    // Existing entries...
    apiGatewayUrl: apiGateway.url,
    };
    }),
    );