{"id":16552182,"url":"https://github.com/dreadwarrior/restlet1-di","last_synced_at":"2026-05-29T21:31:18.127Z","repository":{"id":179541538,"uuid":"630091209","full_name":"dreadwarrior/restlet1-di","owner":"dreadwarrior","description":"Experiment with dependency injection in a Restlet 1.1.x application environment","archived":false,"fork":false,"pushed_at":"2024-05-24T08:13:33.000Z","size":24,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-15T00:32:47.394Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dreadwarrior.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-19T16:42:43.000Z","updated_at":"2023-04-20T13:09:43.000Z","dependencies_parsed_at":"2025-01-15T00:29:43.241Z","dependency_job_id":"bf0e49ba-1a6b-4bbd-848d-d19c089f67da","html_url":"https://github.com/dreadwarrior/restlet1-di","commit_stats":null,"previous_names":["dreadwarrior/restlet1-di"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dreadwarrior%2Frestlet1-di","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dreadwarrior%2Frestlet1-di/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dreadwarrior%2Frestlet1-di/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dreadwarrior%2Frestlet1-di/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dreadwarrior","download_url":"https://codeload.github.com/dreadwarrior/restlet1-di/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241885725,"owners_count":20036955,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T19:44:09.778Z","updated_at":"2025-12-02T00:02:17.973Z","avatar_url":"https://github.com/dreadwarrior.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Restlet 1.1.x example app with Dependency Injection\n\n## Synopsis\n\nWhen working with a legacy Restlet 1.1.x application, it may become difficult to\nestablish automated tests because no dependency injection is in place.\n\nBy getting rid of statically instantiated classes and using integration testing,\nit should become easier to reason about the application, reducing its overall \ncomplexity and improving its architecture.\n\n## Motivation\n\nWhile [Restlet 2.x comes with an extension for using Google Guice for dependency\ninjection](https://restlet.talend.com/documentation/user-guide/2.4/extensions/guice) \nin `Resource`s, Restlet version 1.x comes with no such functionality\nout of the box.\n\nThe approach should be very defensive and should allow minimal effort for \nintegrating DI to the existing application because of missing test coverage.\n\n## Approach\n\n*Production call chain*\n\nThe Guice dependency module is instantiated very early in the application \nlifecycle in the class holding the `main` method and passed to the Restlet \napplication class. See [App](src/main/java/de/dreadlabs/App.java#L15).\n\nThe Restlet application uses a derived Restlet `Router` to hook into the \ninstantiation of attached `Resources` by using a derived Restlet `Finder`. Both\nderived components are \"bridging\" Guice to Restlet, to make use of the Guice \n`Injector` APIs. See\n[ExampleRestletApplication](src/main/java/de/dreadlabs/ExampleRestletApplication.java),\n[GuiceRouter](src/main/java/de/dreadlabs/infrastructure/restletguicebridge/GuiceRouter.java)\nand [GuiceFinder](src/main/java/de/dreadlabs/infrastructure/restletguicebridge/GuiceFinder.java).\n\nThe derived `Finder` is delegating the `Resource` initialization from \nconstructor call (as the built-in Restlet `Finder` does) to the `Resource#init()`\nmethod (which is additionally used by the built-in Restlet `Finder`).\n\n---\n\n**Note**\n\nThis approach may be difficult to integrate, if the existing `Resources` of the\nlegacy application use a complex inheritance hierarchy, when their [constructors\nare not code-free](https://www.yegor256.com/2015/05/07/ctors-must-be-code-free.html) \nor simply \"do too much\".\n\n---\n\n*Test call chain*\n\nIt's now possible to introduce an (integration) base test class which handles\nstarting and stopping the Restlet application. An abstract method allows \nuse-case- or test-specific dependency configuration. See [IntegrationTest](src/test/java/de/dreadlabs/IntegrationTest.java) and [HelloWorldTest](src/test/java/de/dreadlabs/examplefeature/HelloWorldTest.java).\n\n---\n\n**Note**\n\nBefore using this approach, make sure you understand the application's \nbootstrapping process. Check which additional classes and / or packages are \nregistered. For example, application-specific exception mappers could be \nregistered either by the class-based or package-based registration process.\n\nThis is required in order to get reliable integration tests which lean towards\nthe production configuration of the application.\n\n---\n\nA more sophisticated approach, by using JUnit initializer tooling, would be \npossible. This would allow better control for _arrange_ steps in specific test\nmethods.\n\nThis was left out for brevity and for future exercises. :blush:\n\n## Outlook\n\n1. Analyse runtime impacts of derived `Finder` instantiation.\n2. Analyse refactoring efforts on complex `Resource` inheritance hierarchies.\n3. Inspect JUnit initializer tooling for fine-grained control for arrange steps.\n4. Analyse side effects to other `Restlet` components, like `Filter` etc.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdreadwarrior%2Frestlet1-di","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdreadwarrior%2Frestlet1-di","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdreadwarrior%2Frestlet1-di/lists"}