Skip to content

Conversation

@timothygachengo
Copy link
Contributor

@timothygachengo timothygachengo commented Dec 26, 2025

Information

Type Breaking change
Feature No

This PR updates the Apollo integration in the @tsed/apollo package to support both Express 4 and Express 5. The most significant changes are the dynamic selection of Express middleware based on the Express version, the addition of new peer dependencies, expanded tests for different Express versions, and updated documentation for integration steps.

Documentation updates:

  • Updated the README to clarify installation and integration steps for Express 4, Express 5, Koa, and Fastify, and to reflect the new required dependencies and usage patterns.

Dependency updates:

  • Upgraded @apollo/server and graphql dependencies to newer versions.

Todos

  • Tests
  • Coverage
  • Example
  • Documentation

Resources:

Summary by CodeRabbit

  • New Features

    • Added integration support for Express 5, Fastify, and Koa frameworks
    • Implemented automatic Express version detection for optimal middleware compatibility
  • Chores

    • Upgraded Apollo Server to v5.2.0
    • Updated GraphQL to v16.12.0
    • Added optional peer dependencies for framework integrations
  • Tests

    • Expanded test coverage for lifecycle, server creation, and framework-specific scenarios

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 26, 2025

Walkthrough

The PR upgrades Apollo Server to v5, introduces dynamic Express version detection to support both v4 and v5 integrations, adds optional peer/dev dependencies for Express, Koa, and Fastify integrations, updates GraphQL versions, and adds/updates tests and documentation for these changes.

Changes

Cohort / File(s) Summary
Package manifests
packages/graphql/apollo/package.json, packages/graphql/typegraphql/package.json
Bump @apollo/server to ^5.2.0; update graphql to 16.12.0; add devDependencies for @as-integrations/express4, @as-integrations/express5, @as-integrations/fastify; add peerDependencies and peerDependenciesMeta for optional integrations; remove @types/graphql from typegraphql.
Documentation
packages/graphql/apollo/readme.md
Update install instructions to use GraphQL v16; add sections for Express 4/5 and Koa integrations; add Fastify placeholder; small formatting tweaks.
Runtime service
packages/graphql/apollo/src/services/ApolloService.ts
Replace hardcoded Apollo Express4 import with runtime Express-major-version detection and conditional dynamic import of @as-integrations/express5 or @as-integrations/express4; throw on unsupported major versions.
Service tests
packages/graphql/apollo/src/services/ApolloService.spec.ts
Update mocks to use @as-integrations/express4 and add @as-integrations/express5 mocks; simulate express/package.json versions for v4, v5, and unsupported v3; add tests asserting middleware selection and error path.
Module tests
packages/graphql/apollo/src/ApolloModule.spec.ts
New test suite covering settings resolution order, lifecycle hooks ($onRoutesInit, $afterListen), server creation, injector alter flow, and URL logging behaviors.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Module as ApolloModule
  participant Injector
  participant Service as ApolloService
  participant Platform as PlatformConfiguration
  participant ExpressPkg as express/package.json
  rect `#e6f7ff`
    Note right of Module: $onRoutesInit
  end
  Module ->> Injector: $alterApolloSettings (async)
  Injector -->> Module: altered settings?
  Module ->> Service: createServer(id, settings)
  rect `#fff4e6`
    Note right of Service: runtime detection & import
  end
  Service ->> ExpressPkg: read version
  ExpressPkg -->> Service: version string
  alt major == 5
    Service ->> Service: dynamic import `@as-integrations/express5`
  else major == 4
    Service ->> Service: dynamic import `@as-integrations/express4`
  else unsupported
    Service -->> Module: throw unsupported-express-version
  end
  Service ->> Service: apply middleware to platform (use/mount)
  Module ->> Platform: $afterListen -> getBestHost
  Platform -->> Module: host:port
  Module ->> Module: log server URL(s)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is partially related to the changeset, referring to a real aspect of the change (upgrading Apollo Server and integrations) but appears truncated and incomplete with the ellipsis ('and add …'), making it unclear what specific addition is being referenced. Complete the title to clearly convey what is being added. For example: 'feat(apollo): upgrade Apollo Server and add Express 5 support' or 'feat(apollo): upgrade Apollo Server and add multi-framework integrations'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@timothygachengo timothygachengo marked this pull request as ready for review December 26, 2025 11:54
@Romakita
Copy link
Collaborator

Perfect! @timothygachengo

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/graphql/apollo/src/services/ApolloService.ts (2)

70-93: Wrap switch case declarations in a block scope.

Biome correctly flags that const/let declarations inside switch cases without block scope can be erroneously accessed by other cases. Wrap the express case body in braces to restrict variable scope.

🔎 Proposed fix
             switch (this.platformName) {
-              case "express":
-                // use newer graphql express middleware
-                const expressVersion = await import("express/package.json").then((pkg) => pkg.default.version);
-                const majorVersion = parseInt(expressVersion.split(".")[0], 10);
-
-                let expressMiddleware: any;
-
-                if (majorVersion >= 5) {
-                  ({expressMiddleware} = await import("@as-integrations/express5"));
-                } else if (majorVersion === 4) {
-                  ({expressMiddleware} = await import("@as-integrations/express4"));
-                } else {
-                  throw new Error(`Express version ${expressVersion} is not supported. Please use Express 4 or 5.`);
-                }
-
-                this.app.use(
-                  path,
-                  expressMiddleware(server as any, {
-                    ...middlewareOptions,
-                    context: contextHandler
-                  })
-                );
-                break;
+              case "express": {
+                // use newer graphql express middleware
+                const expressVersion = await import("express/package.json").then((pkg) => pkg.default.version);
+                const majorVersion = parseInt(expressVersion.split(".")[0], 10);
+
+                let expressMiddleware: any;
+
+                if (majorVersion >= 5) {
+                  ({expressMiddleware} = await import("@as-integrations/express5"));
+                } else if (majorVersion === 4) {
+                  ({expressMiddleware} = await import("@as-integrations/express4"));
+                } else {
+                  throw new Error(`Express version ${expressVersion} is not supported. Please use Express 4 or 5.`);
+                }
+
+                this.app.use(
+                  path,
+                  expressMiddleware(server as any, {
+                    ...middlewareOptions,
+                    context: contextHandler
+                  })
+                );
+                break;
+              }

95-105: Consider adding block scope to the koa case for consistency.

For consistency with the suggested fix for the express case and to prevent potential issues if this case is extended in the future.

🔎 Proposed fix
-            case "koa":
-              const {koaMiddleware} = await import("@as-integrations/koa");
-
-              this.app.use(
-                path,
-                koaMiddleware(server as any, {
-                  ...middlewareOptions,
-                  context: contextHandler
-                })
-              );
-              break;
+            case "koa": {
+              const {koaMiddleware} = await import("@as-integrations/koa");
+
+              this.app.use(
+                path,
+                koaMiddleware(server as any, {
+                  ...middlewareOptions,
+                  context: contextHandler
+                })
+              );
+              break;
+            }
📜 Review details

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f570161 and 9898ee0.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (6)
  • packages/graphql/apollo/package.json
  • packages/graphql/apollo/readme.md
  • packages/graphql/apollo/src/ApolloModule.spec.ts
  • packages/graphql/apollo/src/services/ApolloService.spec.ts
  • packages/graphql/apollo/src/services/ApolloService.ts
  • packages/graphql/typegraphql/package.json
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prohibit absolute imports between packages within the monorepo; use relative imports instead

Files:

  • packages/graphql/apollo/src/ApolloModule.spec.ts
  • packages/graphql/apollo/src/services/ApolloService.spec.ts
  • packages/graphql/apollo/src/services/ApolloService.ts
**/*.spec.ts

📄 CodeRabbit inference engine (AGENTS.md)

Place test files with .spec.ts naming convention and run via Vitest with per-package configurations

Files:

  • packages/graphql/apollo/src/ApolloModule.spec.ts
  • packages/graphql/apollo/src/services/ApolloService.spec.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: Romakita
Repo: tsedio/tsed PR: 3148
File: packages/platform/platform-express/src/components/PlatformExpress.ts:226-230
Timestamp: 2025-08-20T20:24:35.591Z
Learning: Ts.ED framework defaults to extended query parsing behavior in v4, so maintaining "extended" query parser in Express v5 is preserving existing functionality rather than introducing new behavior that needs migration documentation.
📚 Learning: 2025-12-01T15:26:21.293Z
Learnt from: CR
Repo: tsedio/tsed PR: 0
File: docs/public/ai/AGENTS.md:0-0
Timestamp: 2025-12-01T15:26:21.293Z
Learning: Applies to docs/public/ai/src/**/*.spec.ts : Update or add unit/integration tests near changed files (test/ or src/**/**.spec.ts co-location)

Applied to files:

  • packages/graphql/apollo/src/ApolloModule.spec.ts
  • packages/graphql/apollo/src/services/ApolloService.spec.ts
📚 Learning: 2025-01-29T23:19:32.209Z
Learnt from: LonguCodes
Repo: tsedio/tsed PR: 2974
File: packages/orm/objection/src/decorators/belongsToOne.spec.ts:86-111
Timestamp: 2025-01-29T23:19:32.209Z
Learning: The test suite for `BelongsToOne` decorator in `belongsToOne.spec.ts` focuses on positive cases of relationship mapping configuration. Error cases are not applicable to this test suite as they are likely handled at TypeScript compilation time or in separate validation layers.

Applied to files:

  • packages/graphql/apollo/src/ApolloModule.spec.ts
📚 Learning: 2025-12-01T15:26:21.293Z
Learnt from: CR
Repo: tsedio/tsed PR: 0
File: docs/public/ai/AGENTS.md:0-0
Timestamp: 2025-12-01T15:26:21.293Z
Learning: Use the Ts.ED CLI (tsed/cli) to scaffold controllers, services, DTOs, middlewares, interceptors, and tests to ensure files, names, and boilerplate match current best practices

Applied to files:

  • packages/graphql/apollo/readme.md
📚 Learning: 2024-11-28T13:04:43.555Z
Learnt from: Romakita
Repo: tsedio/tsed PR: 2900
File: packages/platform/platform-test-sdk/src/interfaces/PlatformTestingSdkOpts.ts:6-6
Timestamp: 2024-11-28T13:04:43.555Z
Learning: Les modifications apportées aux fichiers de test internes, tels que `packages/platform/platform-test-sdk/src/interfaces/PlatformTestingSdkOpts.ts`, sont considérées comme internes au repository et n'introduisent pas de breaking change potentiel.

Applied to files:

  • packages/graphql/apollo/src/services/ApolloService.spec.ts
🧬 Code graph analysis (2)
packages/graphql/apollo/src/ApolloModule.spec.ts (4)
packages/platform/platform-http/src/testing/PlatformTest.ts (1)
  • PlatformTest (19-165)
packages/graphql/apollo/src/services/ApolloService.ts (1)
  • ApolloService (18-231)
packages/di/src/common/services/InjectorService.ts (1)
  • InjectorService (54-656)
packages/graphql/apollo/src/interfaces/ApolloSettings.ts (1)
  • ApolloSettings (22-40)
packages/graphql/apollo/src/services/ApolloService.spec.ts (2)
packages/platform/platform-http/src/testing/PlatformTest.ts (1)
  • PlatformTest (19-165)
packages/core/src/utils/catchError.ts (1)
  • catchAsyncError (21-27)
🪛 Biome (2.1.2)
packages/graphql/apollo/src/services/ApolloService.ts

[error] 73-73: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 74-74: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 76-76: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

🪛 LanguageTool
packages/graphql/apollo/readme.md

[grammar] ~55-~55: Ensure spelling is correct
Context: ...e using express you need to install its respecitve integration: - Express 4 - [@as-integr...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.18.1)
packages/graphql/apollo/readme.md

77-77: Spaces inside code span elements

(MD038, no-space-in-code)

🔇 Additional comments (7)
packages/graphql/typegraphql/package.json (1)

41-41: LGTM!

The GraphQL version bump to 16.12.0 aligns with the broader upgrade across the monorepo. Removing @types/graphql is appropriate since GraphQL 16+ ships with built-in TypeScript definitions.

packages/graphql/apollo/src/ApolloModule.spec.ts (1)

1-217: LGTM!

Comprehensive test coverage for ApolloModule including:

  • Settings resolution with proper fallback order (apollo → graphql → typegraphql)
  • $onRoutesInit lifecycle hook with server creation and settings alteration
  • $afterListen hook with URL logging across various host configurations
  • Edge cases for missing settings

The tests correctly use relative imports and follow the .spec.ts co-location pattern.

packages/graphql/apollo/src/services/ApolloService.spec.ts (3)

19-47: LGTM on the mock structure for Express integration tests.

The mock setup correctly separates @as-integrations/express4 and @as-integrations/express5 with distinct return values (expressMiddleware4 and expressMiddleware5), enabling clear test assertions for each Express version path.


307-340: Good coverage for unsupported Express version error path.

The test correctly verifies that createServer throws an appropriate error when an unsupported Express version (3.x) is detected, validating the error message content.


272-306: The test is correctly structured and does exercise the Express 5 code path as intended.

The vi.doMock and vi.doUnmock pattern in the beforeEach/afterEach hooks is the proper Vitest way to override module mocks between tests. When service.createServer("key", opts) is called within the Express 5 test, it performs a fresh dynamic import("express/package.json") that correctly retrieves the mocked version "5.0.0", which leads to importing @as-integrations/express5 and thus calling the mocked expressMiddleware that returns "expressMiddleware5". The assertion expecting app.use to be called with ("/path", "expressMiddleware5") is accurate and will pass.

Likely an incorrect or invalid review comment.

packages/graphql/apollo/package.json (2)

60-72: LGTM on optional peer dependencies structure.

The peerDependenciesMeta correctly marks all integration packages as optional, allowing users to install only the integration they need (Express 4, Express 5, Koa, or Fastify).


30-30: Apollo Server v5 migration is properly implemented.

The upgrade to @apollo/server v5 has been correctly handled. The critical breaking change—Express integration removal—is addressed via the new @as-integrations/express4 and @as-integrations/express5 packages added as devDependencies. ApolloService.ts dynamically imports the appropriate integration based on the Express version in use. The graphql dependency (16.12.0) meets the v5 requirement (≥16.11.0), no deprecated @apollo/server/express* imports remain, and all API usage follows v5 patterns.

@Romakita
Copy link
Collaborator

@timothygachengo just fix typo hightlighted by coderabbit review ;)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9898ee0 and 433df57.

📒 Files selected for processing (1)
  • packages/graphql/apollo/readme.md
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Romakita
Repo: tsedio/tsed PR: 3148
File: packages/platform/platform-express/src/components/PlatformExpress.ts:226-230
Timestamp: 2025-08-20T20:24:35.591Z
Learning: Ts.ED framework defaults to extended query parsing behavior in v4, so maintaining "extended" query parser in Express v5 is preserving existing functionality rather than introducing new behavior that needs migration documentation.
📚 Learning: 2025-12-01T15:26:21.293Z
Learnt from: CR
Repo: tsedio/tsed PR: 0
File: docs/public/ai/AGENTS.md:0-0
Timestamp: 2025-12-01T15:26:21.293Z
Learning: Use the Ts.ED CLI (tsed/cli) to scaffold controllers, services, DTOs, middlewares, interceptors, and tests to ensure files, names, and boilerplate match current best practices

Applied to files:

  • packages/graphql/apollo/readme.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: test-platform (20.19.4)
  • GitHub Check: test-third-parties (20.19.4)
  • GitHub Check: test-graphql (20.19.4)
  • GitHub Check: test-security (20.19.4)
  • GitHub Check: test-specs (20.19.4)
  • GitHub Check: test-orm (20.19.4)
  • GitHub Check: lint (20.19.4)
  • GitHub Check: test-core (20.19.4)
  • GitHub Check: CodeQL-Build
🔇 Additional comments (1)
packages/graphql/apollo/readme.md (1)

53-77: Excellent—all past review issues have been addressed.

The Express Integration (lines 53-67), Koa Integration (lines 69-73), and Fastify placeholder (line 77) sections are now correctly structured. The spelling correction ("respective"), Express 5 package name (@as-integrations/express5), and Fastify formatting are all in place.

@timothygachengo
Copy link
Contributor Author

@Romakita Could you merge this for me please?

@Romakita Romakita merged commit 97a8bc0 into tsedio:production Jan 10, 2026
12 checks passed
@Romakita
Copy link
Collaborator

🎉 This PR is included in version 8.22.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@timothygachengo timothygachengo deleted the upgrade-and-fix-graphql branch January 11, 2026 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants