> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wyrly.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Framework adapters

> Next.js、Express、Hono、Fresh、GraphQL で Wyrly DI を使います。

Wyrly はフレームワーク統合を薄く保ちます。コアパッケージはトークン、プロバイダー、コンテナ、スコープ、検証、グラフ検査を担当します。アダプターはリクエストスコープを作成し、フレームワーク固有の方法で公開します。

## Next.js App Router

インストール:

```sh theme={null}
npm install @wyrly/next @wyrly/core next react
```

Route Handlers では `withDI` を使います。

```ts theme={null}
import { createContainer } from "@wyrly/core";
import { withDI } from "@wyrly/next";

const container = createContainer();

export const GET = withDI(container, async (_req, { di }) => {
  const usecase = di.resolve(MyUseCase);
  return Response.json(await usecase.run());
});
```

Next.js adapter は Server Actions と Server Components 向けの helpers も提供します。

## Express

Express adapter を使うと、1 request につき 1 scope を作り、request object から取得できます。

```ts theme={null}
import { diMiddleware } from "@wyrly/express";

app.use(diMiddleware(container));
```

## Hono

Hono アダプターはエッジ向けのリクエストスコープに使います。

```ts theme={null}
import { di, getDI } from "@wyrly/hono";

app.use("*", di(container));

app.get("/users/:id", async (c) => {
  const scope = getDI(c);
  const usecase = scope.resolve(GetUserUseCase);
  return c.json(await usecase.execute(c.req.param("id")));
});
```

## Fastify

`@wyrly/fastify` は Fastify 5 向けの `diPlugin` を提供します（リクエストごとに 1 scope、レスポンスの
`finish` / `close` で自動 dispose）。peer: `fastify` ^5。`fastify-plugin` によりルートインスタンス全体に
hook が適用されます。

| リソース  | リンク                                                                                         |
| ----- | ------------------------------------------------------------------------------------------- |
| パッケージ | [`packages/fastify`](https://github.com/valid-lab/wyrly/tree/main/packages/fastify)         |
| 例     | [`examples/fastify-api`](https://github.com/valid-lab/wyrly/tree/main/examples/fastify-api) |

```ts theme={null}
import Fastify from "fastify";
import { diPlugin, getDI } from "@wyrly/fastify";

const app = Fastify();
await app.register(diPlugin(container));

app.get("/users/:id", async (request) => {
  const useCase = getDI(request).resolve(GetUserUseCase);
  return { id: await useCase.execute(request.params.id) };
});
```

Fastify 上で GraphQL を使う場合は [`@wyrly/apollo`](https://github.com/valid-lab/wyrly/tree/main/packages/apollo) や [`@wyrly/yoga`](https://github.com/valid-lab/wyrly/tree/main/packages/yoga) と組み合わせます。

## Fresh

Fresh 2.x アプリケーションでは `@wyrly/fresh` を使います。このパッケージは JSR で公開されています。

```sh theme={null}
deno add jsr:@wyrly/fresh
```

## GraphQL

`@wyrly/graphql` で各 GraphQL リクエストに DI スコープを割り当てます。

```ts theme={null}
import { createGraphQLDIContext } from "@wyrly/graphql";

const ctx = await createGraphQLDIContext(container, {
  request,
  configureScope(scope) {
    scope.set(CurrentUserToken, { id: userId });
  },
});

try {
  return await runResolvers(ctx.di);
} finally {
  await ctx.dispose();
}
```

### GraphQL Yoga / Apollo Server

v2.2.0 で専用パッケージ予定。それまでは plugin で dispose します。

| サーバー             | 例                                                                                                 | ガイド                                                                                                 |
| ---------------- | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| GraphQL Yoga 5   | [`examples/yoga-graphql`](https://github.com/valid-lab/wyrly/tree/main/examples/yoga-graphql)     | [GRAPHQL\_DISPOSE.ja.md](https://github.com/valid-lab/wyrly/blob/main/guides/GRAPHQL_DISPOSE.ja.md) |
| Apollo Server 4+ | [`examples/apollo-graphql`](https://github.com/valid-lab/wyrly/tree/main/examples/apollo-graphql) | 同上                                                                                                  |

## Adapter はアプリの外側の層に置く

フレームワークアダプターはアプリケーションの外側の層に置いてください。ドメインオブジェクトや use case は `Request`、`Response`、フレームワークのコンテキストオブジェクトではなく、ポートや値オブジェクトに依存すべきです。
