{"id":38049033,"url":"https://github.com/soasada/undertow-vuejs","last_synced_at":"2026-01-16T20:02:50.260Z","repository":{"id":40994385,"uuid":"175964200","full_name":"soasada/undertow-vuejs","owner":"soasada","description":"Undertow + Vue.js SPA example (login: admin/admin) demo -\u003e","archived":false,"fork":false,"pushed_at":"2025-12-21T17:25:26.000Z","size":350,"stargazers_count":5,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-12-23T06:49:56.962Z","etag":null,"topics":["axios","bulma","bulma-css","bulma-css-framework","java","jdk12","rest-api","undertow","vue","vuejs"],"latest_commit_sha":null,"homepage":"http://uv.popokis.com","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/soasada.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-03-16T11:36:31.000Z","updated_at":"2025-12-21T17:25:27.000Z","dependencies_parsed_at":"2024-10-29T10:37:45.001Z","dependency_job_id":null,"html_url":"https://github.com/soasada/undertow-vuejs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/soasada/undertow-vuejs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soasada%2Fundertow-vuejs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soasada%2Fundertow-vuejs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soasada%2Fundertow-vuejs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soasada%2Fundertow-vuejs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/soasada","download_url":"https://codeload.github.com/soasada/undertow-vuejs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soasada%2Fundertow-vuejs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28482241,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["axios","bulma","bulma-css","bulma-css-framework","java","jdk12","rest-api","undertow","vue","vuejs"],"created_at":"2026-01-16T20:02:49.912Z","updated_at":"2026-01-16T20:02:50.211Z","avatar_url":"https://github.com/soasada.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Web application demo with Undertow + Vue.js\n\n**Inspired in https://github.com/jonashackt/spring-boot-vuejs**\n\nSample project that shows how to build single-page applications with [Undertow](http://undertow.io) and [Vue.js](https://vuejs.org). The project is divided in two modules: **backend** and **frontend**.\n\n## Backend\n\nIn the backend module we have the following dependencies:\n\n* WEB SERVER: **Undertow**. (via popok)\n* RDBMS: **MySQL** (provided in a docker image).\n* DB CONNECTION POOL: **HikariCP**.\n* IMMUTABLE MODELS: **Lombok**.\n* JSON: **Jackson**. (via popok)\n* HTTP AUTHORIZATION: **JWT**.\n* LOGGING: **Log4j2**.\n* TESTING: **JUnit 5**.\n\n**Spring JDBC** (via popok) provides the functionality to use aliases in the SQL queries.\nOne of the solutions is to put prefixes to the column names of the database tables. More info: https://stackoverflow.com/questions/15184709/cachedrowsetimpl-getstring-based-on-column-label-throws-invalid-column-name\n\n**Guava** is optional, is part of a proof of concept with [RequestHandler.java](/backend/src/main/java/com/popokis/undertow_vuejs/http/server/RequestHandler.java) and [ResponseHandler.java](/backend/src/main/java/com/popokis/undertow_vuejs/http/server/ResponseHandler.java). This is a work in progress approach.\n\n### 1. Web server\n\nThe web server is configured via [app.properties](/backend/src/main/resources/app.properties).\n\nThe router of the server is an Undertow HttpHandler you can see it in [Router.java](/backend/src/main/java/com/popokis/undertow_vuejs/http/server/Router.java).\nAll of the HTTP API handlers are wrapped with `BlockingHandler` in [Handlers.java](/backend/src/main/java/com/popokis/undertow_vuejs/http/server/Handlers.java) \nbecause all of them do blocking operations and we execute all these operations in the pool of workers of undertow. One of the reasons of this is the blocking nature of the JDBC.\n\nStatic files are served from the `public` folder inside `resources` folder. The frontend project compiles all the static files and the `maven-resources-plugin` \nmoves the files from `/frontend/target/dist` to `/resources/public` in the backend module. This happens in the backend module compilation.\n\n### 2. Database\n\nThe database is configured via `.properties` files (thanks to HikariCP that supports them) via [db_prod_pool.properties](/backend/src/main/resources/database/db_prod_pool.properties)\nfor production configuration and [db_test_pool.properties](/backend/src/main/resources/database/db_test_pool.properties) for testing.\nThe class responsible of load this config files is: [HikariConnectionPool.java](/backend/src/main/java/com/popokis/undertow_vuejs/db/HikariConnectionPool.java).\n\nIn order to access to the database, I use raw JDBC with a minimal abstraction to build queries ([Query.java](/backend/src/main/java/com/popokis/undertow_vuejs/db/Query.java)) and execute them ([Database.java](/backend/src/main/java/com/popokis/undertow_vuejs/db/Database.java)).\nTo map a table record to an object I made a mapper interface ([JdbcMapper.java](/backend/src/main/java/com/popokis/undertow_vuejs/db/JdbcMapper.java)) to do it manually (the mapping).\nOne of the problems that I have encountered is the aliases problem: If you want to return the `ResultSet` to other layers of your application, \nyou have to store it in some cache and return to the layers. This is because if you close the `ResultSet` you lose the connection and the \n`ResultSet` would be empty. To avoid this situation you can use the `CachedRowSet` class, and then you can close the `ResultSet` and the \nconnection returns to the pool, with the connection closed (returned to the pool) and the record in memory you can map it to an object.\n\n## Frontend\n\nThe frontend module is pretty simple is a back-office application to manage the houses and the furniture of it's users.\n\n## Features\n\n* HTTPs/HTTP2.\n* Redirection from HTTP to HTTPs.\n* Gzip compression for static files.\n* Authorization via JWT.\n* Proxy all frontend requests to our backend.\n* Single artifact deploy.\n* Minimal JDBC abstraction.\n* Migrations.\n* Database testing with docker.\n* Immutable JSON messages.\n* Application configuration.\n* OpenJDK 12 support.\n* Easy backend and frontend testing.\n* Streams data from the backend to the frontend via SSE with Reactor and vanilla undertow.\n\n## Try it!\n\n[Demo here](http://uv.popokis.com), remember to accept risks (self-signed cert), for login use:\\\n`admin`\\\n`admin`\n\n## Steps to deploy\n\n0. Download JDK13 from: https://jdk.java.net/13/ and put in your machine at:\n\n`/opt/prod_jdk`\n\nMaven will use this folder in order to compile the project, this allow us to update easily the JDK version.\nIf you want to have the `java` as a command without typing `/opt/prod_jdk/bin/java` you can do this:\n\n`sudo ln -s /opt/prod_jdk/bin/java /usr/local/bin/java`\n\nor (ubuntu based) add this line at the end of your ~/.bashrc:\n\n`export PATH=/opt/apache-maven-3.6.2/bin:$PATH` (for maven)\\\n`export JAVA_HOME=/opt/prod_jdk`\\\n`export PATH=$PATH:$JAVA_HOME/bin`\n\n1. Compile Vue.js project and generate static files.\n\n`mvn -U clean install -pl :frontend`\n\n2. Remove previous static files.\n\n`rm -rf backend/src/main/resources/public`\n\n3. Test migrations (require a running docker).\n\n`mvn -U clean -pl :backend -Dflyway.configFiles=src/main/resources/database/test_migrations.properties flyway:migrate`\n\n4. Compile backend, move static files to public/ and generate jar file (deployable artifact).\n\n`export APP_ENV=test \u0026\u0026 mvn -U clean compile test package -pl :backend`\n\n5. Run application (change APP_ENV with `prod` or `test`).\n\n`export APP_ENV=test \u0026\u0026 java -Xms64M -Xmx512M -Dlogfilename=web -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -jar backend/target/backend-0.0.1.jar`\n\n**NOTE:** There is a script to deploy locally (_local_deploy.sh_), **use it for development only!**.\n\n## Manifesto\n\nYou don't need a backend framework or an ORM to be able to make web applications, **why not plain java?**.\n_\"Don't reinvent the wheel\"_ they say, and you pick a framework, now you have a **bicycle** with: a washing machine, an embedded\nmicrowave and a neon light beacon... Do you really need all of this features?\n\n**Wait a moment... why are you saying this about frameworks?**\n\nThe problem isn't frameworks, it's us (developers). **Try to learn the basics first, later learn a framework**.\nLearn things like OOP, FP, HTTP, client-server model, plain SQL, VMs... and then, when you know these things, when you are tired\nof doing these things without no help, when you are tired of doing repetitive things only then, take a framework.\n\nMany of the problems that you are going to have with a framework, is due to the lack of knowledge of the framework itself or\n**the basics**. Soon you will have a good amount of spaghetti code unmaintainable, with some modules of your project that \nfits the _\"framework boundaries\"_ and others that use hacks to fit these boundaries with your knowledge of the language,\nresulting in **performance issues**, **cryptic errors**, **updating problems**, **development delays (slow cycles)** and more...\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoasada%2Fundertow-vuejs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoasada%2Fundertow-vuejs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoasada%2Fundertow-vuejs/lists"}