Inject the gift-links service into the API controller at boot#28788
Inject the gift-links service into the API controller at boot#28788rob-ghost wants to merge 1 commit into
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
| Command | Status | Duration | Result |
|---|---|---|---|
nx run ghost:test:ci:integration:no-coverage |
✅ Succeeded | 2m 33s | View ↗ |
nx run ghost:test:ci:integration |
✅ Succeeded | 2m 20s | View ↗ |
nx build @tryghost/sodo-search |
✅ Succeeded | <1s | View ↗ |
nx build @tryghost/admin-toolbar |
✅ Succeeded | <1s | View ↗ |
nx build @tryghost/signup-form |
✅ Succeeded | <1s | View ↗ |
nx build @tryghost/announcement-bar |
✅ Succeeded | <1s | View ↗ |
nx build @tryghost/activitypub |
✅ Succeeded | 2s | View ↗ |
nx build @tryghost/comments-ui |
✅ Succeeded | <1s | View ↗ |
Additional runs (10) |
✅ Succeeded | ... | View ↗ |
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗
☁️ Nx Cloud last updated this comment at 2026-06-22 20:24:05 UTC
Boot constructs the service against the ready DB and passes it straight to the controller factory; the controller closes over a definite instance, so the non-null assertions and the lazy init()/singleton are both gone.
e6d877e to
f60c2fe
Compare
|
FYI @jonatansberg this is the sketch to show what's possible in order to get rid of the optional gift links service global and the Unfortunately it also means we need to have another endpoint singleton which is set as a result of calling I tried to also address this singleton but this blew up the scope completely, so I think this is the limit we can do right now in order to cleanup this service singleton. One thing we might want to explore is putting the endpoint definitions into gift-links itself to co-locate, the same idea as the serialisers PR, which would help actually associate the serialisers with the shape of the endpoints, because right now the endpoints are off in some other place so its hard to associate the endpoint to the return value defined in the serialiser. Shall we explore what that looks like here or in a follow up PR? Or accept this PR as it is? Or drop it entirely? I personally like the idea of a |

Problem
The gift-links API controller read its service from a mutable module export that is undefined until a boot-time
init()ran, so every handler needed a non-null assertion. The service was also instantiated lazily inside its own module rather than wired by the boot sequence, so a future second dependant couldn't easily share the same instance.Solution
Make boot the composition root: it constructs the service against the ready DB and passes it straight to the controller factory (
createController(service)), which closes over a definite instance. The non-null assertions, theinit()indirection, and the mutable service singleton all go away. The only shared slot is the built controller, which the API endpoints index reads — the framework loads controllers lazily, so the boot-built one has to live somewhere it can find.Verified: typecheck and lint clean, and the e2e-api suite (which boots Ghost through this exact path) passes.