{"id":22295783,"url":"https://github.com/danielfernandez/reactive-matchday","last_synced_at":"2025-07-29T01:32:13.960Z","repository":{"id":146695414,"uuid":"74103228","full_name":"danielfernandez/reactive-matchday","owner":"danielfernandez","description":"Spring 5 showcase application with a Thymeleaf HTML5 interface","archived":false,"fork":false,"pushed_at":"2017-11-05T15:11:16.000Z","size":308,"stargazers_count":83,"open_issues_count":1,"forks_count":21,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-05T05:51:12.639Z","etag":null,"topics":["mongodb","reactive-streams","spring","spring-boot","sse","thymeleaf","webflux"],"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/danielfernandez.png","metadata":{"files":{"readme":"README.markdown","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2016-11-18T06:50:10.000Z","updated_at":"2024-05-19T13:07:52.000Z","dependencies_parsed_at":"2023-04-20T20:06:41.348Z","dependency_job_id":null,"html_url":"https://github.com/danielfernandez/reactive-matchday","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/danielfernandez/reactive-matchday","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielfernandez%2Freactive-matchday","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielfernandez%2Freactive-matchday/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielfernandez%2Freactive-matchday/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielfernandez%2Freactive-matchday/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielfernandez","download_url":"https://codeload.github.com/danielfernandez/reactive-matchday/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielfernandez%2Freactive-matchday/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267616566,"owners_count":24116154,"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","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["mongodb","reactive-streams","spring","spring-boot","sse","thymeleaf","webflux"],"created_at":"2024-12-03T17:43:10.705Z","updated_at":"2025-07-29T01:32:13.953Z","avatar_url":"https://github.com/danielfernandez.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\nReactive MatchDay\n------------------\n\n**Reactive MatchDay** is a testing Java application that uses the following technology stack:\n\n   * Thymeleaf 3.0 (`master`:`3.0.9.RELEASE`, `dev`:`3.0.10-SNAPSHOT`)\n   * Spring Boot 2.0.0 (`master`:`2.0.0.M5`, `dev`:`2.0.0.BUILD-SNAPSHOT`)\n   * Spring Framework 5 (`master`:`5.0.0.RELEASE`, `dev`:`5.0.1.BUILD-SNAPSHOT`)\n   * Spring WebFlux (`master`:`5.0.0.RELEASE`, `dev`:`5.0.1.BUILD-SNAPSHOT`)\n   * Spring Data MongoDB (Reactive) (`master`:`2.0.0.RELEASE`, `dev`:`2.0.1.BUILD-SNAPSHOT`)\n   * MongoDB (`3.4+`)\n\nHighlights of this application are:\n\n   * Use of Thymeleaf's integration module for Spring 5's WebFlux reactive web framework.\n   * Use of Thymeleaf's data-driven support for rendering HTML in a reactive-friendly manner.\n   * Use of Server-Sent Events (SSE) rendered in HTML by Thymeleaf from a reactive data stream.\n   * Use of Server-Sent Events (SSE) rendered in JSON by Spring WebFlux from a reactive data stream.\n   * Use of Spring Data MongoDB's reactive (Reactive Streams) driver support.\n   * Use of Spring Data MongoDB's support for infinite reactive data streams based on MongoDB tailable cursors.\n   * Use of Thymeleaf's fully-HTML5-compatible syntax\n   * Use of many weird, randomly generated team and player names.\n\n\n#### Running\n\nFirst make sure MongoDB (3.4+) is running:\n\n```\n$ mongod [your options]\n```\n\nBy default this application will expect MongoDB running on `localhost` with a default configuration\nand no authentication, and it will create a database called `matchday` in your server. If you need\na different configuration you can adjust the connection at the Spring Boot `application.properties`\nfile in the app.\n\nOnce MongoDB is running, just execute from the project's folder:\n\n```\n$ mvn -U clean compile spring-boot:run\n```\n\nThis should start the Spring Boot 2.0 + Spring 5 WebFlux managed Netty HTTP server on port 8080.\nIt also starts two **agents**, separate threads which insert random match events and match comments\ninto MongoDB collections (each n seconds) so that the web interface has some data to show.\n\nOnce started, point your browser to `http://localhost:8080`:\n\n![Matchday: matches page](/doc/matchday_matches.png)\n\nThis first page presents a list of the (randomly generated) football matches that are currently being played in our\nleague. This list of matches is rendered by from a `@Controller` which includes a `Flux\u003cMatchInfo\u003e` \nobject in the `Model`, then calls a Thymeleaf view to be rendered. Before actually rendering,\nSpring WebFlux will fully resolve the `Flux` (non-blocking) so that Thymeleaf can iterate it.\n \nIf you click on *See Match*:\n\n![Matchday: match page](/doc/matchday_match.png)\n\nThis page allows us to follow a specific match. \n\nOn the left side, the current score and the\nlist of events is rendered by means of HTML Server-Sent Events (SSE) retrieved by an `EventSource`\nJavaScript object, which calls a `@Controller` that retrieves the match events as a **MongoDB\ntailable cursor** (see [here](https://docs.mongodb.com/manual/core/tailable-cursors/)) in the\nform of a `Flux\u003cMatchEvent\u003e`. This is put into the model as a Thymeleaf *data-driver context\nvariable* so that Thymeleaf can execute in a reactive-friendly manner and produce SSE events\nrendered in HTML in a reactive way, as MongoDB notifies the application of the existence of\nnew events in the database. So it is MongoDB who effectively pushes its new data into the\napplication, triggering the rendering of a chunk of HTML and its sending to the browser, all of\nthis in a reactive, non-blocking manner.\n\nOn the right side, the comments for the match are retrieved in two steps: \n\n*1st* a list of the *comments so far* (until the moment the `@Controller` executes) are retrieved at the server side\nand put into a Thymeleaf *data-driver context variable*, so that Thymeleaf renders them into HTML\nin a *reactive-friendly* way (non-blocking) as they are returned by MongoDB. This is not a\n *tailable cursor*, so the query cursor actually completes. \n \n *2nd*, once the list reaches the browser, another\n`EventSource` JavaScript object performs a call to a different `@Controller`, which this\ntime collects the rest of the match comments (the ones generated after the moment the page\nwas rendered) in the form of another *tailable cursor*, and renders them in JSON (`@ResponseBody`).\nThis way MongoDB will be able to push new comments inserted by the *comments agent* directly\ntowards the browser in the form of JSON-rendered Server-Sent Events (SSE), which a bit of\nJavaScript at the browser then will parse and insert into the Document Object Model.\n\n---\n\n**NOTE**: This demo application does not work (or style properly) in Microsoft IE/Edge, due to the lack of\nsupport for `EventSource` in these browsers. Several polyfill options exist to palliate this, but they have\nnot been applied to this application for the sake of simplicity.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielfernandez%2Freactive-matchday","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielfernandez%2Freactive-matchday","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielfernandez%2Freactive-matchday/lists"}