Skip to Content
Technical Articles
Author's profile photo Rafael Lopez Martinez

How to build End-to-End custom applications in Cloud Foundry

Cloud%20Foundry%20React%20Angular%20Vue%20CAP%20Hana

Hi developer!

Cloud Foundry is really cool! Many of us are continuously exploring it and pushing our new projects there.

However, I’m sure many of you struggled a bit to create and deploy your apps to Cloud Foundry. Documentation is spread, and in a typical configuration (Node.js backend app + HANA + Angular / React / Vue.js / UI5 / or whatever HTML5 app…) there are many things to connect and orchestrate

Don’t worry, we are here to help…

A few weeks ago I published a post about the tool my colleagues @Alberto Delgado, @Sergio Delgado and myself have build to create and deploy End-to-End apps to Cloud Foundry with just one command. Jump to the following link if you want to use it and make it work in minutes: https://blogs.sap.com/2020/07/29/cf-create-app-create-end-to-end-apps-and-deploy-to-cloud-foundry-in-minutes/

Today I’m going to explain how configure all of this step by step, following a meaningful order, describing important details to take into account, and pointing to the documentation when possible.

Let’s start…

Index

  1. What are we building?
  2. Requirements
  3. Recommended
  4. Step-by-Step Configuration
    1. Create a CAP Project
    2. Add a HANA database to your project
    3. Deploy your app with MTA
    4. Add an HTML5 custom application as your FrontEnd app
    5. The Application Router

 

What are we building?

  • A Node.js backend application and a HANA database instance, exposing your services via OData. We will use Cloud Application Programming Model (CAP) for this.
  • An HTML5 application in your frontend side. No matter if using React, Angular, Vue.js, UI5 or any other HTML5 tech you like.
  • An application router to dispatch you request to the correct place.
    Configure your mta.yaml file to deploy everything as an MTA application.

Requirements

In your computer:

Node.js v12 Download
Cloud Foundry CLI Download
Cloud Application Model CLI Download

In your SCP Cloud Foundry account, you need access to the following services:

HTML5 Application Repository html5-apps-repo
SAP HANA Schemas & HDI Containers hana
Authorization & Trust Management xsuaa

Recommended

The MTA plugin for CF CLI Download
HTML5 Applications Repository CF CLI Plugin Download

Step-by-Step configuration

1. Create a CAP Project

Navigate to your workspace and create a new CAP project running:

cds init your-app-name

This creates the backend application barebones with the recommended project structure and required dependencies. Read more about this in CAP documentation – Getting Started

Create a schema.cds file in the db/ folder and define your entities.

Read more about CDS Entity and Type definition in CAP documentation – Definition Language CDL (Entity and Type definitions)

Create a yourServiceName-service.cds file in the srv/ folder and declare your services.

Read more about CDS Service definition in CAP documentation – Definition Language CDL (Services)

2. Add a HANA database to your project

To persist your data in the cloud you might want to use a HANA database. To be able to add a HANA DB to your project, you have to log in to your CF account first:

cf login -a CF_ACCOUNT_API_ENDPOINT

Follow the command prompt to enter your credentials and select the space where you want access the HANA Instance.

Then add a HANA DB to the project with:

cds add hana

This command adds a db/src/.hdiconfig file with the required information to conect to your HANA instance in the cloud, and sets the db “kind” to “hana” in your project package.json file.

To be able to bind a HANA instance you must suscribe to SAP HANA Schemas & HDI Containers service via the Service Marketplace in your SAP Cloud Platform space.

3. Deploy your app with MTA

To deploy apps to our Cloud Foundry environment we will use the MTA concept.

MTA allows to deploy multiple application artifacts in one single file, making the process much simpler and avoiding errors. To know more about MTA visit the documentation.

Add the MTA descriptor file

cds add mta

Create your build archive and deploy it

mbt build 
cf deploy mta_archives/<your-app-mtar-archive-name>.mtar

Once the deployment is finished, the console logs the application endpoint as follows:

Application "my-srv" started and available at "csi-development-team-factory-cfaccount-sandbox-cap-boil36d2a520.cfapps.eu10.hana.ondemand.com"

This is your API endpoint.

4. Add an HTML5 custom application as your FrontEnd app

At this point you probably want to add an UI to your application, and this could be a quite big topic depending on your needs.

There is no technology limitations in this area, so you can use whatever HTML5 and JavaScript based technology like SAP UI5, ReactJS, Angular, VueJS, or plain HTML5 and vanilla JavaScript for example.

As you can imagine, it is not feasible to make a tutorial for all the option in the market. The following lines detail the process for the most common options, so it can guide you to follow an equivalent path for any other technology you might choose.

Adding a ReactJS application

Create your React Application in the /app folder:

cd app/ 
npx create-react-app .
Adding an Angular application

Use angular CLI to create your app in the /app folder:

npm install -g @angular/cli   #Skip this command if you already have Angular CLI installed in your computer
ng new app
Adding a Vue.js application

Use Vue CLI to create your app in the /app folder:

npm install -g @vue/cli   #Skip this command if you already have Vue CLI installed in your computer
vue create app

 

4.1 Set your application ID

To host our HTML5 application we use the HTML5 Application Repository service.

To know more about this service visit the documentation

To identify our app in the HTML5 Application Repository, we have to provide an ID in the manifest.json file.

If this file doesn’t exist yet, create it and make sure it is included in the application build.

In the manifest.json file add the following lines:

{ 
  ... 
  "sap.app": { 
    "id":"yourHtml5ApplicationId", 
    "applicationVersion":{ 
      "version": "1.0.0" 
    }
  }
}

Make sure yourHtml5ApplicationId is unique in your HTML5 Application Repository. If there is another HTML5 application with the same id in the HTML5 Application Repository, a new deployment will overwrite it.

4.2 Add HTML5 Deployer

HTML5 application deployer handles the upload of the HTML5 applications content to the HTML5 Application Repository.

For more information about the HTML5 Application Deployer read the documentation

  1. Creates an html5Deployer/ folder in the app root directory.
  2. Add a new package.json file in the new html5Deployer/ folder with the following content.
{
	"name": "html5Deployer",
	"engines": {
		"node": ">=6.0.0"
	},
	"dependencies": {
		"@sap/html5-app-deployer": "2.0.0"
	},
	"scripts": {
		"start": "node node_modules/@sap/html5-app-deployer/index.js"
	}
}

 

4.3 Update MTA.yaml file to include the HTML5 Application

Edit the mta.yaml file with your favorite text editor.

  1. Add deploy_mode: html5-repo to the main parameters block
parameters: 
  enable-parallel-deployments: true
  deploy_mode: html5-repo
  1. Add the commands to build your HTML5 application to the before-all > commands block.
- npm --prefix ./app install ./app 
- npm run build --prefix ./app
  1. Add the following code to the modules block
 # --------------------- HTML5DEPLOYER MODULE -----------------
 - name: my-hmtl5-deployer
 # ------------------------------------------------------------
   type: com.sap.html5.application-content
   path: html5Deployer
   requires:
    - name: my-html5-host
   build-parameters:
    requires:
      - name: my-app
        artifacts:
          - './*'
        target-path: resources/app

 # --------------------- REACT APP MODULE ---------------------
 - name: my-app
 # ------------------------------------------------------------
   type: html5
   path: app
   build-parameters:
      supported-platforms: []
      build-result: build        # This is the folder containing the build files
  1. Add the following code to the resources block
 # --------------------- HTML5 Runtime ----------------------
 - name: my-html5-runtime
 # ------------------------------------------------------------
   parameters:
     service-name: my-html5-runtime
     service-plan: app-runtime
     service: html5-apps-repo
   type: org.cloudfoundry.managed-service

# --------------------- HTML5 Host -------------------------
 - name: my-html5-host
# ------------------------------------------------------------
   parameters:
     service-name: my-html5-host
     service-plan: app-host
     service: html5-apps-repo
   type: org.cloudfoundry.managed-service

You can change the name of your modules and resources, making them consistant with your project name. If you do it, make sure you keep the relationships between modules and resources using the correct names in the requires and provides blocks.

5. The Application Router

The application router is the single point-of-entry for an application running in the Cloud Foundry environment on SAP Cloud Platform. The application router is used to serve static content, authenticate users, rewrite URLs, and forward or proxy requests to other microservices while propagating user information.

The following diagram illustrates where the App Router sits in a typical Cloud Foundry architecture:

Cloud Foundry diagram with App Router

This diagram includes a connection to an on-premise system which we will not see in this tutorial. Please review this document for more details about this scenario.

5.1 Add the Application Router to the project

  1. Creates an approuter/ folder in the app root folder.
  2. Add a new package.json file in the new approuter/ folder with the following content.
{
  "name": "approuter",
  "version": "1.0.0",
  "description": "My App Router",
  "dependencies": {
    "@sap/approuter": "^6.8.2"
  },
  "scripts": {
    "start": "node node_modules/@sap/approuter/approuter.js"
  }
}
  1. Add a new xs-app.json file in the new approuter/ folder with the following content.
{	
  "welcomeFile": "/index.html",
  "authenticationMethod": "none",
  "routes":[{
    "source":"^(.*)",
    "target":"yourHtml5ApplicationId/$1",
    "service":"html5-apps-repo-rt"
  }]
}

The yourHtml5ApplicationId must be the same included in the application manifest.json file, explained in the Step 4.1.

The xs-app.json file describes the App router behaviour, like routing, authentication method, etc.
The configuration proposed above sends every HTTP request to the HTML5 application, with no authentication required. To modify this bahaviour, please read the documentacion

5.2 Add XSUAA resource

Edit the mta.yaml file with your favourite text editor.

  1. Add the following code to the resources block:
# --------------------- XSUAA Service ---------------------
 - name: my-xsuaa
# ------------------------------------------------------------
   parameters:
      path: ./xs-security.json
      service-plan: application
      service: xsuaa
   type: org.cloudfoundry.managed-service
  1. Create the xs-security.json file in root folder of the project with the following code
{
    "xsappname": "my-approuter",
    "tenant-mode": "dedicated",
    "description": "Security profile of called application",
    "scopes": [
      {
        "name": "uaa.user",
        "description": "UAA"
      }
    ],
    "role-templates": [
      {
        "name": "Token_Exchange",
        "description": "UAA",
        "scope-references": [
          "uaa.user"
        ]
      }
    ]
}

 

5.3 Update MTA.yaml file to include the App Router

Edit the mta.yaml file with your favorite text editor.

  1. Add the following code to the modules block:
 # --------------------- APPROUTER MODULE ---------------------
 - name: my-approuter
 # ------------------------------------------------------------
   type: approuter.nodejs
   path: approuter
   requires:
    - name: my-html5-runtime
    - name: my-xsuaa

 

6. Access data from your HTML5 app

To consume the services defined with CAP in Step 1 (and therefore, the data in our HANA DB) we have to set a destination pointing to our backend service (the CAP application) and configure the App Router to manage routing accordingly.

6.1 Set a destination in your mta.yaml file

Modify the App Router module definition as follows:

# --------------------- APPROUTER MODULE ---------------------
 - name: my-approuter
# ------------------------------------------------------------
   type: approuter.nodejs
   path: approuter
   requires:
    - name: my-html5-runtime
    - name: my-xsuaa
    - name: srv-binding
      group: destinations
      properties:
        name: srv-binding
        url: ~{srv-url}
        forwardAuthToken: true

 

6.2 Configure your App Router to use the destination

The following configuration sets the Application Router to redirect all the <host>:<port>/api requests to your backend service via the destination called srv-binding. Any other request will be redirected to the HTML5 application

{	
  "routes":[{
    "source": "/api/(.*)",
    "target": "$1",
    "destination": "srv-binding",
    "authenticationType": "none"
  },{
    "source":"^(.*)",
    "target":"yourHtml5ApplicationId/$1",
    "service":"html5-apps-repo-rt"
  }]
}

 

7. Re-deploy your application with the new components

Run:

mbt build
cf deploy mta_archives/<your-app-mtar-archive-name>.mtar

You can always get your MTA applications details running the command:

cf mta <your-mta-app-ID>

Find the MTA App ID in the mta.yaml file

cf mta command is only available if your installed the MTA plugin for CF CLI mentioned in the README file > Recommended tools

What’s next?

Cool! Now you know how to build and deploy your apps to Cloud Foundry. You have now many possibilities to explore, and I am sure it will not be difficult to enhance your apps digging a bit into the documentation provided.

Remember that you can skip all this manual configuration and have everything ready in a few minutes, using the tool I mention at the beginning: https://blogs.sap.com/2020/07/29/cf-create-app-create-end-to-end-apps-and-deploy-to-cloud-foundry-in-minutes/

And do not hesitate to leave a comment if you have any insights, ideas, feedback, errors, or just want to share how useful was this for you.

Cheers

Assigned Tags

      15 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Hemsagar Elugu
      Hemsagar Elugu

      Great Blog ! Liked the content.

      Author's profile photo Rafael Lopez Martinez
      Rafael Lopez Martinez
      Blog Post Author

      Glad you like it Hemsagar Elugu. Hope it helps you.

      Author's profile photo pratheek reddy
      pratheek reddy

      Hi,

      This is a very useful blog but I have one problem here.

      I'm not able to use the destinations in local development in the react module.

      Author's profile photo Rafael Lopez Martinez
      Rafael Lopez Martinez
      Blog Post Author

      Hi pratheek reddy,

      I don't know exactly what you cannot do, but I think the React proxy middleware will help you to achive that you need: https://create-react-app.dev/docs/proxying-api-requests-in-development/

      Cheers,

      Rafa

      Author's profile photo ELI NAIM
      ELI NAIM

      4.1 you are saying to add json to manifest file, but didnt say which manifest? where to create it?

      Author's profile photo Rafael Lopez Martinez
      Rafael Lopez Martinez

      Hi ELI NAIM, in this section we are talking about the UI code, so it should be available in the the folder where all the UI code is.

      In case of react for example, the manifest.json file will be available by default in the /public folder. So if you followed the tutorial step by step, it should be available in /app/public folder.

      Best,
      Rafael

      Author's profile photo Cristian Abad Chico
      Cristian Abad Chico

      Rafael Lopez Martinez ,

       

      Very nice blog, many thanks for sharing!

      A couple of things.

      - Is it possible to have more than 1 react app in the same project?

      - Is there any Git repo where I can see some examples? I would be interested in seeing how to consume the CAP services from a React based UI.

      Thanks,

      C.

      Author's profile photo Rafael Lopez Martinez
      Rafael Lopez Martinez

      Hi Cristian Abad Chico ,

      1. Yes, as any other project you can have your backend server exposing an API, and as many frontend apps as you want consuming that API. In this case, you can use CAP to design your data model and expose it via OData, and then use whatever frontend tech you want to build your apps and consume that OData service.
      2. I don't have a public repo available right now, but I think it will be very easy for you to do it without a repo. Just follow the CAP Getting Started documentation to create a headless CAP project (without frontend), deploy it and save the URL to your service. If you want to add security as well, you just need to add the AppRouter as described in the post. Then create a React app and use that URL to consume data as any other REST API. Deploy your React app wherever you like and it should work.

      Best,

      Rafael

       

      Author's profile photo Shireen Sheikh
      Shireen Sheikh

      I have a question...Do applications deployed on cloud foundry run continuosly or go down in the night?

      Author's profile photo Rafael Lopez Martinez
      Rafael Lopez Martinez

      Hi Shireen Sheikh ,

      As far as I know, they run continuously.

      However there are multiple configurations you can do, and if you are using the free trial account I'm not sure if they shut it down at some point.

      Best,
      Rafa

      Author's profile photo Nicolas Cerda
      Nicolas Cerda

      Hi Rafael Lopez Martinez

       

      Thank you so much for this Post and for the cf-create-app cli tool, I'm trying it and it looks great so far.

       

      I wanted to ask you a question,

       

      let's say that I have a nodejs app already created using some nodejs framework (like express). This app already has some functionality and I want to consume it from my frontend app.

      ¿Should I consume this app using CAP? ¿How would you structure this end-to-end application so my custom nodejs app can be deployed with alongside with the rest of the project? ¿could you recommend me some sources I could look into to do something like this?

       

      Thank you so much!

      Author's profile photo Rafael Lopez Martinez
      Rafael Lopez Martinez

      Hi Nicolas Cerda ,

      CAP is not mandatory at all. It is just a framework that helps you to build CF backend apps in the SAP recommended way, which has tons of advantages, but all is optional.

      Of course you can deploy to CF your Node+Express app (nothing to do with CAP). You just need to configure an mta.yaml file to get the files from the folder where the "build" is. You can probably copy the whole mta.yaml file that CAP generates for you in a new project, paste it in your Express project and just modify the "path" property to point to your build.

      I think it should be something like this

        # --------------------- SERVER MODULE ------------------------
        - name: your-server-module-name
          # ------------------------------------------------------------
          type: nodejs
          path: build # this should point to the folder where your build is
          properties:
            EXIT: 1 # required by deploy.js task to terminate

       

      So my recommendation would be:
      1- Deploy your Express app configuring the mta.yaml file as I just told you
      2- Setup a destination and the AppRouter as described in the post. Deploy it and get the URL.
      3- Create your frontend app in an independent project and configure the mta.yaml file as described in the post (you can separate this in completely independent folder/repo). Use the URL from step 2 to consume your Express API

      OTHER OPTION:
      You can even do both things. CAP runs on top of an Express instance, and if you want to build custom endpoints you can easily access the Express instance and define your endpoints as you are used to. You can even combine an OData service generated with CAP with your own Express endpoints.

      Just create a server.js file in the project and access the express "app" object in the "bootstrap" event: https://cap.cloud.sap/docs/node.js/cds-serve#custom-server-js

      Best,
      Rafa

      Author's profile photo Aditi Anand
      Aditi Anand

      Hi,

      Thanks for a great blog. This blog helped me a lot in creating a MTA application with React as front-end.

      I followed the exact above steps for creating app. In my React App, I am using react-router for routing. In development mode, routing is working fine, even on refreshing the browser I am getting the desired page. But after deploying to cloud foundry, routing is working only on clicking buttons. If I am on some internal page, and I refreshes the browser, blank page opens, the content does not get loaded.

      Can you help me here please. Is there any additional configuration required for approuter?

       

      Author's profile photo Rafael Lopez Martinez
      Rafael Lopez Martinez

      Hi Aditi Anand ,

      Not sure how to help you here without knowing more, but first thing that comes into my mind is that your AppRouter configuration is not routing correctly when you use a deep link. As it is a SPA, you should make sure your AppRouter points to your index.html file always I guess, even when the URL does not point the "home page" of your app. Once the index.html file is loaded in your browser, the react router code will be executed and render the desired page.

      Hope it helps,
      Rafa

      Author's profile photo Tiago Tavares
      Tiago Tavares

      Hello,

      Would it be possible to just deploy my React frontend and use an external API to the calls? Or do I must migrate all my infrastructure?

      All the best,

      Tiago