{"id":22881282,"url":"https://github.com/ngallagher/chero","last_synced_at":"2025-03-31T15:50:21.525Z","repository":{"id":50080075,"uuid":"188107245","full_name":"ngallagher/chero","owner":"ngallagher","description":"Ultra Fast Dependency Injection","archived":false,"fork":false,"pushed_at":"2022-12-14T20:37:14.000Z","size":3083,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-02-06T21:31:06.038Z","etag":null,"topics":["dependency-injection","java","micro-framework","microservices-architecture","rest","rest-api","simple","simple-api","simple-framework","websocket-application","websocket-library","websocket-server"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ngallagher.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-22T20:14:44.000Z","updated_at":"2022-08-16T12:20:19.000Z","dependencies_parsed_at":"2023-01-29T00:46:02.111Z","dependency_job_id":null,"html_url":"https://github.com/ngallagher/chero","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngallagher%2Fchero","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngallagher%2Fchero/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngallagher%2Fchero/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngallagher%2Fchero/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ngallagher","download_url":"https://codeload.github.com/ngallagher/chero/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246491539,"owners_count":20786199,"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":["dependency-injection","java","micro-framework","microservices-architecture","rest","rest-api","simple","simple-api","simple-framework","websocket-application","websocket-library","websocket-server"],"created_at":"2024-12-13T17:32:36.691Z","updated_at":"2025-03-31T15:50:21.497Z","avatar_url":"https://github.com/ngallagher.png","language":"Java","readme":"![Chero](https://raw.githubusercontent.com/ngallagher/chero/master/simple-module/src/main/resources/logo-small.png)\n\nChero is a framework for building micro-services. It includes dependency injection and a web framework with\nsupport for HTTP and WebSocket communication. The dependency injection system is built on the \nultra fast [Class Graph](https://github.com/classgraph/classgraph) project and the web \nframework has a close resemblance to [JAX-RS](https://github.com/jax-rs/api). \n\nThe core objective of this project is to provide a suite of frameworks that are simple to reason about\nwhile offering the benefits of dependency injection and the convenience of declarative annotation \ndriven resources and services.\n\n### Overview\n\nChero offers a lightweight ultra fast dependency injection system with strict scoping constraints. It \nhas been largely inspired by [Spring Boot](https://github.com/spring-projects/spring-boot) \nand [JAX-RS](https://github.com/jax-rs/api). Rather than expanding on the concepts and functionality\navailable in these well know libraries, this framework offers a reduced set of features in order\nto provide a much faster and more deterministic dependency injection system. The result is a simpler\nmore approachable route to building your micro-services.\n\nThe framework is built around the concept of modules and components. A module is a class with the @Module \nannotation. It forms the basis of the dependency injection\nframework by constraining the scope of the application. Scoping restricts the loading of components to\nthe module package and its children. In addition to\napplying these constraints they act as component providers through methods declared with the \n@Provides annotation. All other components are those classes within the module scope declared with \nthe @Component annotation. The @Import annotation allows a module to expand the application scope\nby including a dependent module and its components.\n\n```java\n@Module\n@Import(MailModule.class)\npublic class LoginModule {\n\n\t@Provides\n\tpublic LoginService loginService() {\n\t\t// ...\n\t}\n}\n\n@Module\npublic class MailModule {\n\n\n\t@Provides\n\tpublic MailClient mailClient() {\n\t\t// ...\n\t}\n}\n\n@Component\npublic class MailService {\n\n\tprivate final MailClient client;\n\t\n\tpublic MailService(MailClient client) {\n\t\tthis.client = client;\n\t}\n}\n```\n\n#### Core Framework\n\nThe annotations for the core framework\n\n| Annotation      | Description   | \n| ------------- | ------------- | \n| @Module       | Specify a module to load components from              |\n| @Import       | Import components from another module              |\n| @Provides       | Provide a component from a module method              |\n| @Component       | Component loaded from the class path              |\n| @Value       | Value taken from the command line a configuration file              |\n| @DefaultValue       | Default value used if there is no explicit setting            |\n| @Inject       | Inject a component from the component manager              |\n| @Require       | Determines if a component is required               |\n| @When       | Load the component when the evaluation passes              |\n| @WhenExists       | Load the component if the specified class is a component               |\n| @Unless       | Reject a component if the evaluation passes              |\n| @UnlessExists       | Reject a component if the specified class is a component              |\n\nA complementary library is provided to facilitate exposing functionality though HTTP and WebSockets. This\nframework is largely inspired by [JAX-RS](https://github.com/jax-rs/api) but does not follow the \nofficial specification as this limits the usefulness and functionality of the library. Below is an example\nof how you would declare a resource.\n\n```java\n@Path(\"/login\")\npublic class LoginResource {\n\n\tprivate final LoginService service;\n\t\n\tpublic LoginResource(LoginService service) {\n\t\tthis.service = service;\n\t}\n\n\t@POST\n\t@Path(\"/register/{type}\")\n\t@Produces(\"application/json\")\n\tpublic AccessRequest register(\n\t\t@PathParam(\"type\") UserType type,\n\t\t@QueryParam(\"user\") String user,\n\t\t@QueryParam(\"email\") String email,\n\t\t@QueryParam(\"password\") String password)\n\t{\n\t\treturn service.register(type, user, email, password); \n\t}\n\t\n\t@POST\n\t@Path(\"/grant\")\n\t@Produces(\"application/json\")\n\tpublic AccessGrant grant(\n\t\t@QueryParam(\"user\") String user,\n\t\t@QueryParam(\"token\") String token)\n\t{\n\t\treturn service.grant(user, token);\n\t}\n}\n\n```\n\n#### Web Framework\n\nThe annotations representing HTTP verbs.\n\n| Annotation      | Description   | \n| ------------- | ------------- | \n| @GET       | An idempotent method that is used to retrieve or read state             |\n| @POST       | A mutation that updates the state of the service              |\n| @PUT       | An idempotent method that is used o write state              |\n| @DELETE       | A mutation that updates the state of the service               |\n| @PATCH       | A mutation to a specific part of an entity or resource              |\n| @CONNECT       | Used to connect through the service              |\n\nThe annotations for the core framework.\n\n\n| Annotation      | Description   | \n| ------------- | ------------- | \n| @Path       | A path annotation specifies a resource             |\n| @PathParam       | A parameter from the path expression              |\n| @QueryParam       | A query parameter from the request entity              |\n| @HeaderParam       | Header from the request entity              |\n| @CookieParam       | Cookie send from the client in the request entity              |\n| @Attribute       | An attribute is something that is attached to the request              |\n| @Consumes       | Specifies the content type accepted              |\n| @Produces       | Specifies the content type represented               |\n| @CacheControl       | Cache control settings for the response               |\n| @Attachment       | Content disposition settings for the response               |\n| @Filter       | Filter executed before the resource              |\n| @Subscribe      | Subscribe to a web socket               |\n| @Entity        | Transient component used to hold request and dependency state              |\n\nBelow is an example application that responds asynchronously.\n\n```java\n@Module\npublic class DemoApplication {\n   \n   @Path\n   public static class DemoResource {\n      \n      @Value(\"${message}\")\n      private String text;\n      \n      @GET\n      @Path(\"/.*\")\n      @Produces(\"text/plain\")\n      public CompletableFuture\u003cResponseEntity\u003e helloWorld() {\n         return CompletableFuture.supplyAsync(() -\u003e ResponseEntity.create(Status.OK)\n            .type(\"text/plain\")\n            .cookie(\"TEST\", \"123\")\n            .entity(text)\n            .create()\n         );\n      }\n   }\n   \n   public static void main(String[] list) throws Exception {\n      Application.create(ServerDriver.class)\n         .module(DemoApplication.class)\n         .create(list)\n         .name(\"Demo/1.0\")\n         .session(\"SESSIONID\")\n         .threads(10)\n         .start()\n         .bind(8787);\n   }\n}\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngallagher%2Fchero","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fngallagher%2Fchero","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngallagher%2Fchero/lists"}