{"id":13753799,"url":"https://github.com/amoAHCP/vxms","last_synced_at":"2025-05-09T21:35:52.050Z","repository":{"id":2572958,"uuid":"46881384","full_name":"amoAHCP/vxms","owner":"amoAHCP","description":"vxms is a Vert.x based micro service framework","archived":false,"fork":false,"pushed_at":"2024-12-15T14:21:05.000Z","size":11574,"stargazers_count":31,"open_issues_count":10,"forks_count":9,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-06T17:51:48.506Z","etag":null,"topics":["event-driven","kubernetes","microservice","microservice-framework","react","rest","vertx"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amoAHCP.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":"2015-11-25T19:14:42.000Z","updated_at":"2024-12-15T14:21:11.000Z","dependencies_parsed_at":"2025-02-08T17:41:27.174Z","dependency_job_id":null,"html_url":"https://github.com/amoAHCP/vxms","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amoAHCP%2Fvxms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amoAHCP%2Fvxms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amoAHCP%2Fvxms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amoAHCP%2Fvxms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amoAHCP","download_url":"https://codeload.github.com/amoAHCP/vxms/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253329013,"owners_count":21891562,"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":["event-driven","kubernetes","microservice","microservice-framework","react","rest","vertx"],"created_at":"2024-08-03T09:01:29.879Z","updated_at":"2025-05-09T21:35:50.411Z","avatar_url":"https://github.com/amoAHCP.png","language":"Java","funding_links":[],"categories":["vertx","开发框架"],"sub_categories":["微服务框架"],"readme":"[![Build Status](https://travis-ci.org/amoAHCP/vxms.svg?branch=master)](https://travis-ci.org/amoAHCP/vxms)\n\n# vxms\nVxms is a modular micro-service framework, based 100% on Vert.x 3. While Vert.x is a totally unopinionated framework/toolkit, Vxms helps developers to create REST/event based (micro) services with a clear, uniform and easy to use fluent-API. \n\nSince Vxms is extending Vert.x you can still use all capabilities of Vert.x and mix it with Vxms wherever you like/need. \n\nThe intention for Vxms was to create a framework on top of the powerful Vert.x framework, allowing developers quickly to create services with the focus on writeability, readability and resilience. \nBasically, most of todays service endpoints need to handle requests, process data and be aware of the error handling. This is the focus of Vxms. \n\nVert.x is very powerful, but many developers still struggling with the reactive style and the callback handling in Vert.x. This is the keypoint of Vxms, which provides an easy to use API for \"everyday\" endpoint development.\n\nCurrently vxms consists of 1 base module and 3 extension modules, helping the developer to write Jax-RS like REST services, EventBus endpoints and doing service discovery in Kubernetes. The *core module* is using a Java SPIs to include the REST and EventBus modules, so you can adopt the API easily for your needs.\nVxms only uses Vert.x-core and Vert.x-web extension as dependencies and any other Vert.x extension will work in vxms out of the box.\n    \n## maven dependencies\n\n### vxms-core  [link](https://github.com/amoAHCP/vxms/tree/master/vxms-core)\n```xml\n \u003cdependency\u003e\n      \u003cgroupId\u003eorg.jacpfx\u003c/groupId\u003e\n      \u003cartifactId\u003evxms-core\u003c/artifactId\u003e\n      \u003cversion\u003e1.1\u003c/version\u003e\n \u003c/dependency\u003e\n```   \n### vxms-rest  [link](https://github.com/amoAHCP/vxms/tree/master/vxms-rest)\n```xml\n  \u003cdependency\u003e\n       \u003cgroupId\u003eorg.jacpfx\u003c/groupId\u003e\n       \u003cartifactId\u003evxms-rest\u003c/artifactId\u003e\n       \u003cversion\u003e1.1\u003c/version\u003e\n  \u003c/dependency\u003e\n```   \n### vxms-event bus  [link](https://github.com/amoAHCP/vxms/tree/master/vxms-event)\n```xml\n \u003cdependency\u003e\n        \u003cgroupId\u003eorg.jacpfx\u003c/groupId\u003e\n        \u003cartifactId\u003evxms-event\u003c/artifactId\u003e\n        \u003cversion\u003e1.1\u003c/version\u003e\n  \u003c/dependency\u003e\n```   \n\n### vxms-k8s-discovery [link](https://github.com/amoAHCP/vxms/tree/master/vxms-k8sdiscovery)\n```xml\n \u003cdependency\u003e\n        \u003cgroupId\u003eorg.jacpfx\u003c/groupId\u003e\n        \u003cartifactId\u003evxms-k8sdiscovery\u003c/artifactId\u003e\n        \u003cversion\u003e1.1\u003c/version\u003e\n  \u003c/dependency\u003e\n```   \n\n\n## vxms-rest example\n\n```java\n@ServiceEndpoint(port=8090)\npublic class RESTExample extends VxmsEndpoint {\n\n   \n    @Path(\"/hello/:name\")\n    @GET\n    public void simpleNonBlocking(RestHandler handler) {\n      String name =   handler.request().param(\"name\");\n      handler.\n                      response().\n                      stringResponse((response)-\u003e\n                              response.complete(\"hello World \"+name)). // complete non-blocking response\n                      timeout(2000). // timeout for stringResponse handling. If timeout is reached, error handling will be executed\n                      onError(error -\u003e LOG(error.getMessage())).  // intermediate error handling, will be executed on each error\n                      onFailureRespond((error, future) -\u003e future.complete(\"error:\"+error.getMessage())). // define final error response when (if no retry is defined or all retries are failing)\n                      httpErrorCode(HttpResponseStatus.BAD_REQUEST). // http error code in case of onFailureRespond will be executed\n                      retry(3). // amount of retries before onFailureRespond will be executed\n                      closeCircuitBreaker(2000). // time after circuit breaker will be closed again. While opened, onFailureRespond will be executed on request\n                      execute(); // execute non blocking\n    }\n    \n     @Path(\"/helloChain/:name\")\n     @GET\n     public void simpleNonBlockingChain(RestHandler handler) {\n       String name =  handler.request().param(\"name\");\n       handler.\n                       response().\n                       \u003cInteger\u003esupply((future) -\u003e future.complete(getAge())). // start the chain by supplying a value (an Integer)\n                       \u003cCustomer\u003eandThen((value, future) -\u003e future.complete(new Customer(value + 1 + \"\", name))). // take the value (the Integer) from supply and return an other type (the Customer)\n                       mapToStringResponse((customer, response)-\u003e\n                               response.complete(\"hello World \"+customer.getName())). // get the return-value from the last chain step and map it to a string-response and complete non-blocking response\n                       timeout(2000). // timeout for stringResponse handling. If timeout is reached, error handling will be executed\n                       onError(error -\u003e LOG(error.getMessage())).  // intermediate error handling, will be executed on each error\n                       onFailureRespond((error, future) -\u003e future.complete(\"error:\"+error.getMessage())). // define final error response when (if no retry is defined or all retries are failing)\n                       httpErrorCode(HttpResponseStatus.BAD_REQUEST). // http error code in case of onFailureRespond will be executed\n                       retry(3). // amount of retries before onFailureRespond will be executed\n                       closeCircuitBreaker(2000). // time after circuit breaker will be closed again. While opened, onFailureRespond will be executed on request\n                       execute(); // execute non blocking\n        }\n    \n    @Path(\"/helloBlocking/:name\")\n    @GET\n    public void simpleBlocking(RestHandler handler) {\n       String name =   handler.request().param(\"name\");\n       handler.\n                       response().\n                       blocking().\n                       stringResponse(()-\u003e{\n                            String val = blockingCall();\n                            return val+ \"hello World \"+name;\n                       }). // complete blocking response\n                       timeout(15000). // timeout for stringResponse handling. If timeout is reached, error handling will be executed\n                       onError(error -\u003e LOG(error.getMessage())).  // intermediate error handling, will be executed on each error\n                       onFailureRespond((error, future) -\u003e future.complete(\"error:\"+error.getMessage())). // define final error response when (if no retry is defined or all retries are failing)\n                       httpErrorCode(HttpResponseStatus.BAD_REQUEST). // http error code in case of onFailureRespond will be executed\n                       retry(3). // amount of retries before onFailureRespond will be executed\n                       delay(1000). // delay between retries\n                       closeCircuitBreaker(2000). // time after circuit breaker will be closed again. While opened, onFailureRespond will be executed on request\n                       execute(); // execute non blocking\n          \n     }\n     \n     @Path(\"/helloEventbus/:name\")\n     @GET\n     public void simpleEventbusCall(RestHandler handler) {\n        String name =   handler.request().param(\"name\");\n        handler.\n                        eventBusRequest().\n                        send(\"/hello\", name). // send message to eventbus onSuccess\n                        mapToStringResponse((message, response)-\u003e\n                                     response.complete(message.result().body()). // on message response, map message result value to the rest response                        ). // complete non-blocking response\n                        timeout(5000). // timeout for mapToStringResponse handling. If timeout is reached, error handling will be executed\n                        onError(error -\u003e LOG(error.getMessage())).  // intermediate error handling, will be executed on each error\n                        onFailureRespond((error, future) -\u003e future.complete(\"error:\"+error.getMessage())). // define final error response when (if no retry is defined or all retries are failing)\n                        httpErrorCode(HttpResponseStatus.BAD_REQUEST). // http error code in case of onFailureRespond will be executed\n                        retry(3). // amount of retries before onFailureRespond will be executed\n                        closeCircuitBreaker(2000). // time after circuit breaker will be closed again. While opened, onFailureRespond will be executed on request\n                        execute(); // execute non blocking\n               \n          }\n     \n     private String blockingCall(){\n        // block\n        return \"xyz\";\n     } \n\n    public static void main(String[] args) {\n        Vertx.vertx().deployVerticle(RESTExample.class.getName());\n    }\n}\n``` \n\n## vxms-eventbus example\n\n```java\n@ServiceEndpoint\npublic class EventbusExample extends VxmsEndpoint {\n\n   \n    @Consume(\"/hello\")\n    public void simpleNonBlocking(EventbusHandler handler) {\n      String name =   handler.request().body();\n      handler.\n                      response().\n                      stringResponse((response)-\u003e\n                              response.complete(\"hello World \"+name)). // complete non-blocking response\n                      timeout(2000). // timeout for stringResponse handling. If timeout is reached, error handling will be executed\n                      onError(error -\u003e LOG(error.getMessage())).  // intermediate error handling, will be executed on each error\n                      onFailureRespond((error, future) -\u003e future.complete(\"error:\"+error.getMessage())). // define final error response when (if no retry is defined or all retries are failing)\n                      retry(3). // amount of retries before onFailureRespond will be executed\n                      closeCircuitBreaker(2000). // time after circuit breaker will be closed again. While opened, onFailureRespond will be executed on request\n                      execute(); // execute non blocking\n    }\n    \n     @Consume(\"/helloChain\")\n     public void simpleNonBlocking(EventbusHandler handler) {\n       String name =   handler.request().body();\n       handler.\n                      response().\n                      \u003cInteger\u003esupply((future) -\u003e getAge()). // start the chain by supplying a value (an Integer)\n                      \u003cCustomer\u003eandThen((value, future) -\u003e future.complete(new Customer(value + 1 + \"\", name))). // take the value (the Integer) from supply and return an other type (the Customer)\n                       mapToStringResponse((cust, response)-\u003e\n                            response.complete(\"hello World \"+cust.getName())). // get the return-value from the last chain step and map it to a string-response and complete non-blocking response\n                       timeout(2000). // timeout for stringResponse handling. If timeout is reached, error handling will be executed\n                       onError(error -\u003e LOG(error.getMessage())).  // intermediate error handling, will be executed on each error\n                       onFailureRespond((error, future) -\u003e future.complete(\"error:\"+error.getMessage())). // define final error response when (if no retry is defined or all retries are failing)\n                       retry(3). // amount of retries before onFailureRespond will be executed\n                       closeCircuitBreaker(2000). // time after circuit breaker will be closed again. While opened, onFailureRespond will be executed on request\n                       execute(); // execute non blocking\n        }\n    \n   \n    public static void main(String[] args) {\n        Vertx.vertx().deployVerticle(EventbusExample.class.getName());\n    }\n}\n```\n\n## vxms-k8s-discovery example\n\n```java\n@ServiceEndpoint(port=8090)\n@K8SDiscovery\npublic class RESTExample extends VxmsEndpoint {\n\n     @ServiceName()\n     @WithLabels({\n       @WithLabel(name = \"name\", value = \"${read_name}\"),\n       @WithLabel(name = \"version\", value = \"${read_version}\")\n     })\n     private String read;\n   \n     @ServiceName()\n     @WithLabels({\n       @WithLabel(name = \"name\", value = \"${write_name}\"),\n       @WithLabel(name = \"version\", value = \"${write_version}\")\n     })\n     private String write;\n     \n     \n     ...\n\n\n    public static void main(String[] args) {\n       // this is only for local discovery to bypass Kubernetes in local environments\n       DeploymentOptions options =\n              new DeploymentOptions()\n                  .setInstances(1)\n                  .setConfig(\n                      new JsonObject()\n                          .put(\"kube.offline\", true)\n                          .put(\"local\", true)\n                          .put(\"read_name\", \"vxms-k8s-read\")\n                          .put(\"read_version\", \"1.2-SNAPSHOT\")\n                          .put(\"write_name\", \"vxms-k8s-write\")\n                          .put(\"write_version\", \"1.2-SNAPSHOT\")\n                          .put(\"name.vxms-k8s-read.version.1.2-SNAPSHOT\", \"localhost:7070\")\n                          .put(\"name.vxms-k8s-write.version.1.2-SNAPSHOT\", \"localhost:9090\"));\n        Vertx.vertx().deployVerticle(RESTExample.class.getName(), options);\n    }\n}\n``` \n\n## vxms-core example\n\n```java\n   @ServiceEndpoint\n   public class SimpleService extends VxmsEndpoint {\n   \n      public void postConstruct(Router router, final Future\u003cVoid\u003e startFuture){\n             router.get(\"/hello\").handler(helloGet -\u003e helloGet.response().end(\"simple response\"));\n      }\n      \n      public static void main(String[] args) {\n              Vertx.vertx().deployVerticle(SimpleREST.class.getName());\n       }\n   } \n``` \n\nor using plain Verticles with static initializer\n\n```java\n   @ServiceEndpoint\n   public class SimpleService extends AbstractVerticle {\n  \n      @Override\n      public void start(io.vertx.core.Future\u003cVoid\u003e startFuture) throws Exception {\n        VxmsEndpoint.start(startFuture, this);\n      }\n   \n      public void postConstruct(Router router, final Future\u003cVoid\u003e startFuture){\n             router.get(\"/hello\").handler(helloGet -\u003e helloGet.response().end(\"simple response\"));\n      }\n      \n      public static void main(String[] args) {\n              Vertx.vertx().deployVerticle(SimpleREST.class.getName());\n       }\n   } \n``` \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FamoAHCP%2Fvxms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FamoAHCP%2Fvxms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FamoAHCP%2Fvxms/lists"}