{"id":23288099,"url":"https://github.com/jensborch/webhooks4j","last_synced_at":"2025-07-11T08:34:48.509Z","repository":{"id":37834827,"uuid":"233200765","full_name":"jensborch/webhooks4j","owner":"jensborch","description":"Small, simple and extendable Java library for messaging using webhooks","archived":false,"fork":false,"pushed_at":"2025-07-01T03:21:20.000Z","size":1672,"stargazers_count":5,"open_issues_count":10,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-01T04:27:27.605Z","etag":null,"topics":["cdi","cdi-event","event-driven","event-sourcing","java","java-8","mongodb","webhooks"],"latest_commit_sha":null,"homepage":null,"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/jensborch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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,"zenodo":null}},"created_at":"2020-01-11T08:33:10.000Z","updated_at":"2025-07-01T03:21:23.000Z","dependencies_parsed_at":"2023-02-17T12:00:27.973Z","dependency_job_id":"94480815-0ee0-4a36-8390-f41a3eb40a5b","html_url":"https://github.com/jensborch/webhooks4j","commit_stats":{"total_commits":868,"total_committers":7,"mean_commits":124.0,"dds":0.4608294930875576,"last_synced_commit":"ff074a6cc1cc6a7f2120e743583e85753114ac3d"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/jensborch/webhooks4j","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jensborch%2Fwebhooks4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jensborch%2Fwebhooks4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jensborch%2Fwebhooks4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jensborch%2Fwebhooks4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jensborch","download_url":"https://codeload.github.com/jensborch/webhooks4j/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jensborch%2Fwebhooks4j/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264766093,"owners_count":23660693,"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":["cdi","cdi-event","event-driven","event-sourcing","java","java-8","mongodb","webhooks"],"created_at":"2024-12-20T03:13:49.614Z","updated_at":"2025-07-11T08:34:48.456Z","avatar_url":"https://github.com/jensborch.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Webhooks4j\n\nSmall, simple and extendable Java library for messaging using webhooks and CDI events.\n\n## Status\n\n[![Build](https://github.com/jensborch/webhooks4j/actions/workflows/build.yml/badge.svg)](https://github.com/jensborch/webhooks4j/actions/workflows/build.yml)\n\n[![codecov](https://codecov.io/gh/jensborch/webhooks4j/branch/master/graph/badge.svg)](https://codecov.io/gh/jensborch/webhooks4j)\n\n[![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=com.github.jensborch.webhooks4j%3Awebhooks4j\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=com.github.jensborch.webhooks4j%3Awebhooks4j)\n\nWebhooks4j is used in production.\n\n## Introduction\n\nWebhooks4j is a simple Java library for implementing messaging using webhooks and event-sourcing, that does not need any infrastructure. It is meant to work for simple use cases where message brokers like [Kafka](https://kafka.apache.org/) are not needed. The library is based on the publish–subscribe pattern.\n\nTo subscribe to a topic, inject `WebhookSubscriptions` and call the subscribe method:\n\n```Java\nimport com.github.jensborch.webhooks.Webhook;\nimport com.github.jensborch.webhooks.subscriber.WebhookSubscriptions;\n\n@Inject\nWebhookSubscriptions subscriptions;\n\nWebhook webhook = new Webhook(new URI(\"http://publisher-host/context-root\"), new URI(\"http://subscriber-host/context-root\"), \"my-topic\");\nsubscriptions.subscribe(webhook.state(Webhook.State.SUBSCRIBE));\n```\n\nTo publish events, inject a `WebhookPublisher` and call the publish method:\n\n```Java\nimport com.github.jensborch.webhooks.WebhookEvent;\nimport com.github.jensborch.webhooks.publisher.WebhookPublisher;\n\n@Inject\nWebhookPublisher publisher;\n\nMap\u003cString, Object\u003e eventData = new HashMap\u003c\u003e();\npublisher.publish(\"my-topic\", eventData));\n```\n\nTo receive event use the CDI `@Observes` annotation:\n\n```Java\nimport com.github.jensborch.webhooks.WebhookEvent;\nimport com.github.jensborch.webhooks.WebhookEventTopic;\n\npublic void observe(@Observes @WebhookEventTopic(\"my-topic\") final WebhookEvent event) {\n    //Process the event\n}\n```\n\nThe library is build using [CDI 1.2](http://www.cdi-spec.org/), [JAX-RS 2.0](https://github.com/jax-rs), [Jackson](https://github.com/FasterXML/jackson) and [SLF4J](http://www.slf4j.org/). Usage of SLF4J version 1.6.0 or higher is assumed.\n\nCDI 1.2 is used to be compatible with as many application servers as possible. This imposes some constraints and the solution thus currently do not support asynchronous CDI events and generic event data.\n\n## Getting started\n\nAdded the following dependency for a subscriber:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.jensborch.webhooks4j\u003c/groupId\u003e\n    \u003cartifactId\u003ewebhooks4j-subscriber\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nand\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.jensborch.webhooks4j\u003c/groupId\u003e\n    \u003cartifactId\u003ewebhooks4j-subscriber\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nfor a publisher.\n\nFor MongoDB support add:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.jensborch.webhooks4j\u003c/groupId\u003e\n    \u003cartifactId\u003ewebhooks4j-mongodb-subscriber\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nand/or\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.jensborch.webhooks4j\u003c/groupId\u003e\n    \u003cartifactId\u003ewebhooks4j-mongodb-publisher\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nIf MongoDB is not use for persistence, it is necessary to implement `WebhookEventStatusRepository` and `WebhookRepository` repository interfaces.\n\nThe MongoDB dependency requires [POJO](https://mongodb.github.io/mongo-java-driver/3.12/bson/pojos/) support, see examples below.\n\nCDI producers must be defined for:\n\n- javax.ws.rs.client.Client\n- com.github.jensborch.webhooks.WebhookTTLConfiguration (required for MongoDB, otherwise optional)\n- com.github.jensborch.webhooks.subscriber.WebhookSyncConfiguration (required only by subscriber module)\n- com.mongodb.client.MongoDatabase (for MongoDB support)\n\nand the following REST exposure classes:\n\n- com.github.jensborch.webhooks.subscriber.SubscriberEventExposure\n- com.github.jensborch.webhooks.subscriber.SubscriberWebhooksExposure\n- com.github.jensborch.webhooks.publisher.PublisherEventExposure\n- com.github.jensborch.webhooks.publisher.PublisherWebhookExposure\n\nshould be registered in your JAX-RS application class, depending on how you do JAX-RS configuration.\n\nAdditionally it might be necessary to configure Jackson by implementing ContextResolver\u003cObjectMapper\u003e, as the `Jdk8Module` and `JavaTimeModule` are required.\n\nAn example application using [Quarkus](https://quarkus.io/) can be found in the Maven test module.\n\n### Examples\n\nJAX-RS client producer:\n\n```Java\n@Dependent\npublic class ClientProducer {\n\n    @Produces\n    @Publisher\n    public Client getPublisherClient() {\n        return ClientBuilder.newClient();\n    }\n\n    @Produces\n    @Subscriber\n    public Client getSubscriberClient() {\n        return ClientBuilder.newClient();\n    }\n\n}\n```\n\nMongo database producer:\n\n```Java\n@ApplicationScoped\npublic class WebhookMongoDBProducer {\n\n    @Inject\n    private MongoClient client;\n\n    @Produces\n    @Subscriber\n    @Publisher\n    public MongoDatabase mongoDatabase() {\n         return client.getDatabase(\"MyDatabase\");\n    }\n\n}\n```\n\nNote, this requires an additional CDI producer for `MongoClient`, but it is possible to configure a `MongoClient` directly instead. If no codecs for `ZonedDateTime` and `URI` exists, register the following codec class:\n\n- com.github.jensborch.webhooks.mongodb.URICodec\n- com.github.jensborch.webhooks.mongodb.ZonedDateTimeCode\n\nJAX-RS application class:\n\n```Java\n@ApplicationPath(\"/\")\npublic class MyApplication extends Application {\n\n    @Override\n    public Set\u003cClass\u003c?\u003e\u003e getClasses() {\n        Set\u003cClass\u003c?\u003e\u003e classes = new HashSet\u003c\u003e(Arrays.asList(\n                MyExposure.class,\n                SubscriberEventExposure.class,\n                SubscriberWebhooksExposure.class,\n                PublisherEventExposure.class,\n                PublisherWebhookExposure.class,\n        ));\n        return classes;\n    }\n}\n```\n\nJackson ContextResolver class:\n\n```Java\n@Provider\n@Produces(MediaType.APPLICATION_JSON)\n@Consumes(MediaType.APPLICATION_JSON)\npublic class ObjectMapperProvider implements ContextResolver\u003cObjectMapper\u003e {\n\n    @Override\n    public ObjectMapper getContext(final Class\u003c?\u003e objectType) {\n        ObjectMapper objectMapper = new ObjectMapper();\n        objectMapper.registerModule(new Jdk8Module());\n        objectMapper.registerModule(new JavaTimeModule());\n        return objectMapper;\n    }\n\n}\n```\n\n## Security\n\nAll endpoints are secured using JAX-RS roles. To access subscriber end-point, the __subscriber__ role is needed. To access publisher endpoints the __publisher__ role is need. The are some exceptions to this, as a __publisher__ is allowed to POST callback events to a subscriber end-point. Refer to the Swagger documentation for the [publisher](../master/publisher-swagger.yaml) and [subscriber](../master/subscriber-swagger.yaml) for details.\n\nWhen creating the JAX-RS Client CDI producer, filters should be added to handle security correctly. A simple HTTP Basic access authentication filter can be found in the Maven test module.\n\n## Visualization of the codebase\n\n![Visualization of the codebase](./diagram.svg)\n\n## Building\n\nThe Webhooks4j is build using Maven.\n\nTo build the application run the following command:\n\n```sh\n./mvnw package\n```\n\nInstall the application in your local maven repository (required for running locally)\n\n```sh\n./mvnw install\n```\n\nStart the test application using:\n\n```sh\n./mvnw compile -pl test quarkus:dev\n```\n\nCall endpoints using VSCode RestClient or similar. See webhooks4j.http\n\nRun mutation tests:\n\n```sh\n./mvnw eu.stamp-project:pitmp-maven-plugin:run\n```\n\nRelease to Maven central, see https://central.sonatype.org/publish/publish-maven/ for details:\n\n```sh\n./mvnw release:clean release:prepare -Prelease\n./mvnw release:perform -Prelease\n````\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjensborch%2Fwebhooks4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjensborch%2Fwebhooks4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjensborch%2Fwebhooks4j/lists"}