I have been working on a Vue 3 web application. It allows the user to upload photographs and it will display the locations where these photos were taken on map – using the embedded location details. The user can add their own locations – by clicking on the map – as well as add more images to the sites. This application is a static web application,. It runs entirely inside the browser – almost as a classic desktop application. No backend is used.
Until now I have published the application on GitHub. This is easy to do and free. It does not tell me how often the application is accessed. And it does not allow me to take the next step with my application, which is to add a backend with a persistent storage for the users’ photo-maps. I want to move my app to Oracle Cloud Infrastructure – leveraging its free tier as well as several convenient mechanisms (API Gateway and Object Storage as well as logging for starters). In this article I report on the steps I had to take – from scratch – to be able to have users access my application from the OCI environment.
The final result will look like this:
The most interesting part is the URL that refers to an API Gateway on OCI (that internally references an OCI Object Storage Bucket endpoint):
In brief, these are the steps.
- Build the Vue application for distribution
- Create a Bucket on OCI Object Storage
- Move all application assets to this bucket
- Create a Pre Authenticated Request (PAR) for this bucket
- Try to access the application using this PAR (note: the index.html is loaded just fine but none of the other assets are)
- Create an API Gateway (after first creating a Virtual Cloud Network with public subnet)
- Create a deployment on API Gateway to forward requests to the assets in the Object Storage Bucket using the Pre Authenticated Request; add a second route to cater for the /foto-map base configuration – leading to the same Bucket’s PAR
- Access the index.html file of the application on the endpoint of the API Gateway deployment to run the web application
Build the Vue application for distribution
Create a Bucket on OCI Object Storage (in a Compartment)
First I create a new compartment
With the result:
Then I create the bucket on Object Storage to hold the static web application:
Here it is:
Move all application assets to this bucket
Now it is time to upload the static web application distribution. Two uploads: the files in the /dist folder and secondly the files in /dist/assets:
and the assets:
note the Object Name Prefix “/assets” that is interpreted as a nested directory.
Create a Pre Authenticated Request (PAR) for this bucket
Try to access the application using this PAR (note: the index.html is loaded just fine but none of the other assets are)
Using the URL for the Pre Authenticated Request, I can have my browser download the index.html file of the web application. Other files in the applications however are referenced at the /foto-map/ path – because of the base property in the vite.config.js file – and Object Storage does not understand this.
Perhaps I can create a nested directory at foto-map and copy all files and directories to it – but I will go for a better solution, leveraging API Gateway.
Create an API Gateway (after first creating a Virtual Cloud Network with public subnet)
I will use an API Gateway deployment to handle requests for the assets of which my application is composed. In order to do so in my fresh compartment I need a VCN with a public subnet to associate with the API Gateway. The VCN Wizard in the OCI Portal makes it very easy to quickly configure the VCN.
Click Start VCN Wizard
Enter VCN Name and accept all default:
Press Next
Then press Create:
And subsequently view the results:
These steps take less than 3 minutes.
One finetuning step in the public subnet of the VCN is the definition of an Ingress Rule to allow incoming HTTPS requests into the subnet – requests from any source targeted at port 443:
With the VCN set up I can now continue with the API Gateway.
I call it fotomapp-gateway. It is public and it is linked to the public subnet in the VCN I just created.
Press Create Gateway – and wait for a few minutes while it is deployed.
Create a deployment on API Gateway to forward requests to the assets in the Object Storage Bucket
A deployment is a configuration of routing rules. Requests received on a certain path (“/”) are to be processed/forwarded as GET requests to the Object Storage bucket that contains the static web application’s assets. To access these assets, we can use the Pre Authenticated Request. Shown below is the the creation of a deployment.
There is no authentication enforced at the moment (the web application is publicly available). Only GET requests are supported. And the target URL is composed of the PAR to which is added: “/${request.path[object]}”. This is an expression that is dynamically replaced with the name (and if applicable the nested directory) of the requested file.
A second route is added to the deployment to handle requests at path /fot0-map/
The requests for assets from the static website will go to /foto-map/ because that is the base property’s value in the Vite build configuration.
This second route is to cater for the /foto-map base configuration – and forwards requests to the same Bucket’s PAR as the requests to path “.”
Access the index.html file of the application on the endpoint of the API Gateway deployment to run the web application
After these steps, it almost worked. The index.html loads, images are loaded, all assets are found and I can even see some left over logging in the browser console. However, what I do not see is the Vue components being rendered. I need to extend my router configuration: the routes / and /fot0-map/ are not sufficient because I have to explicitly access /foto-map/index.html in my URL as is shown in the screenshot.
The router component determines the component to route to based on the current location. Because index.html needs to be explicitly addressed, this route needs to be explicitly defined as well.
With this last bit of configuration done and the application rebuilt and reuploaded to the Bucket in Object Storage, I can finally access the application in my browser through API Gateway and from Object Storage.
The fact that the application is accessed is easily noticed in the API Gateway runtime metrics:
Using the API Gateway gives me quick insight in the popularity of the application. As well as in the volume of data and the latency of request handling.
As a next step I can add use of caching capabilities in the deployment to reduce the strain on the backend and reduce latency. However, OCI Object Storage is pretty fast and can handle some strain so I am not sure there us much to be gained.
Leveraging a persistent backend to have the user authenticate and save changes to be reused at a later moment is another next step I am contemplating.
Resources
Article on Medium by Ivan Delic – How to Host Static Website in the OCI Object Storage – https://medium.com/oracledevs/how-to-serve-website-static-files-from-the-oci-object-storage-bd79ca0805c7
OCI Docs on Object Storage Pre Authentication Request – https://docs.oracle.com/en-us/iaas/Content/Object/Tasks/usingpreauthenticatedrequests.htm
OCI Docs on Object Storage Set Up OCI Object Storage and Oracle API Gateway for Static Website Hosting – https://docs.oracle.com/en/learn/oci-api-gateway-web-hosting/index.html
Next step: Hostname and attach custom SSL certificate by Ivan Delić on Medium – https://medium.com/oracledevs/how-to-change-oci-api-gateway-hostname-and-attach-custom-ssl-certificate-bd513f1d5188