How to use Cloud Foundry to serve Spring Boot web app with Vue front end and H2 database?

5/29/2019

I have followed a tutorial using Vue as front end and using spring boot as backend. I write the front end and put the built files from Vue's dist folder to spring boot web's src\main\resources\static folder.

The tutorial told me to use axios to transfer data to the backend. It's configuration is as follows:

var axios = require('axios')
axios.defaults.baseURL = 'http://localhost:8090/api'

It works good on my local pc. But I want to put it and make it run on cloud. I build the jar with mvn clean install. Then uploaded it to IBM's cloud foundry. The frontend works. However, it does not talk to the backend. The browser's console log shows:

XHR failed loading: OPTIONS "<URL>".
4xhr.js:178 OPTIONS http://localhost:8090/api/login net::ERR_CONNECTION_REFUSED

The demo is uploaded here

I also want to include H2 database, but I tried and it only works on mem mode or file mode. The jdbc:h2:tcp://localhost/~/test mode does not work on the cloud. So how to make it run on the cloud? Is there anyother way to make Vue talk with the java backend without axios? Or if it's must, can I configure cloud foundry to make the link work? Or if cloud foundry can't do this, (I use cloud foundry just because it's easy, just upload the jar, no need to configure) can k8s do this?

-- Haz Wof
cloudfoundry
kubernetes
spring-boot
vue.js

1 Answer

5/29/2019

XHR failed loading: OPTIONS "". 4xhr.js:178 OPTIONS http://localhost:8090/api/login net::ERR_CONNECTION_REFUSED

This is failing because your app is no longer running on your local machine, it's running on Cloud Foundry. You need to update your axios.defaults.baseURL setting to reference the route that you bound to your app.

You could hard code this in the config, which is not great but does work, or you could reference the VCAP_APPLICATION environment variable which is set by Cloud Foundry and contains information about your app, including the bound routes (there can be more than one). You could read this, pick a route and dynamically configure your app.

Ex:

 "VCAP_APPLICATION": {
  "application_id": "<guid>",
  "application_name": "<app-name>",
  "application_uris": [
   "app-name.apps.example.com",
   "some-other-route.example.com"
  ],
  "application_version": "df82308c-7add-4f2b-bb44-a58680084a79",
  "cf_api": "https://api.system.example.com",
  "limits": {
   "disk": 1024,
   "fds": 16384,
   "mem": 64
  },
  "name": "<app-name>",
  "space_id": "<space-guid>",
  "space_name": "<space-name>",
  "uris": [
   "app-name.apps.example.com",
   "some-other-route.example.com"
  ],
  "users": null,
  "version": "df82308c-7add-4f2b-bb44-a58680084a79"
 }

I also want to include H2 database, but I tried and it only works on mem mode or file mode. The jdbc:h2:tcp://localhost/~/test mode does not work on the cloud.

I don't see why this technically wouldn't work, so long as you're app is talking to the database over localhost, all the traffic would be inside the app container. You'd have to be more specific about what exactly is failing.

That said, I don't think you'd want to use H2 like that, at least not beyond a small test/demo. First off, the app containers are ephemeral, so none of your data would survive a restart/crash/restage/push or anything that triggers the container to restart (platform maintenance can do this too, so it's not just actions you initiate). Second, you really wouldn't be able to scale your app beyond one instance because each instance of the app would have it's own copy of the database, which is going to be problematic.

What you really want to do is create a service & bind that to your app. Then, just like VCAP_APPLICTION, you can pull your service credentials from VCAP_SERVICES and dynamically configure your app to connect to your database. See the second part of this answer for details on how to do that.

Try running cf marketplace to see a list of the services your provider offers. Many services even have free tier service plans, so you can try them or use them for small apps and demos.

Hope that helps!

-- Daniel Mikusa
Source: StackOverflow