Claude Code Plugins

Community-maintained marketplace

Feedback

api-contract

@aitchwhy/dotfiles
3
0

Typed HTTP APIs with @effect/platform HttpApiBuilder

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name api-contract
description Typed HTTP APIs with @effect/platform HttpApiBuilder
allowed-tools Read, Write, Edit, Grep
token-budget 450

api-contract

Why HttpApiBuilder

  • Type-safe request/response schemas
  • Automatic client generation
  • Built-in error handling
  • OpenAPI spec generation
  • NO framework lock-in (no Hono, Express)

Define API Contract

import { HttpApi, HttpApiEndpoint, HttpApiGroup } from "@effect/platform";
import { Schema } from "effect";

const UserSchema = Schema.Struct({
  id: Schema.String,
  name: Schema.String,
  email: Schema.String,
});

class UsersApi extends HttpApiGroup.make("users")
  .add(
    HttpApiEndpoint.get("getUser", "/users/:id")
      .setPath(Schema.Struct({ id: Schema.String }))
      .addSuccess(UserSchema)
  )
  .add(
    HttpApiEndpoint.post("createUser", "/users")
      .setPayload(Schema.Struct({ name: Schema.String, email: Schema.String }))
      .addSuccess(UserSchema)
  ) {}

class MyApi extends HttpApi.empty.add(UsersApi) {}

Implement Handlers

import { HttpApiBuilder } from "@effect/platform";

const UsersApiLive = HttpApiBuilder.group(MyApi, "users", (handlers) =>
  handlers
    .handle("getUser", ({ path }) =>
      Effect.gen(function* () {
        const repo = yield* UserRepository;
        return yield* repo.findById(path.id);
      })
    )
    .handle("createUser", ({ payload }) =>
      Effect.gen(function* () {
        const repo = yield* UserRepository;
        return yield* repo.create(payload);
      })
    )
);

Generate Client

import { HttpApiClient } from "@effect/platform";

// Type-safe client from API definition
const client = HttpApiClient.make(MyApi, {
  baseUrl: "https://api.example.com",
});

// Usage
const user = yield* client.users.getUser({ path: { id: "123" } });