Skip to Content
Technical Articles
Author's profile photo Dries Van Vaerenbergh

SAP Approuter – User API Service

Hi Community,

What is an app without a logged in user to roam around an consume your services?

Nothing, exactly!

But when we finally have our logged in user to use the app, we also want to display his/her user information.

Which could be done like the example below for instance:

Above example is a combination of the following two UI5 controls:

An SAPUI5 Tool Header: Samples – Demo Kit – SAPUI5 SDK (ondemand.com)

An SAPUI5 Avatar: Samples – Demo Kit – SAPUI5 SDK (ondemand.com)

Back then on the SAP Cloud Platform NEO Environment, there was the possibility to consume the “userapi” service by adding a route to the “neo-app.json” file. This allowed the developer to retrieve the current logged in user information such as name, firstName, lastName, displayName and email.

But then a new era arose, the SAP Cloud Platform Cloud Foundry Environment era. Which brought so many possibilities with it, that developing became even more fun! But there was one small catch bound to this Cloud Foundry Environment. We developers lost our NEO “userapi” … But we always find a solution for everything and very often they are shared on the SAP Community. But it meant that an alternative with some custom developments were required to retrieve the necessary information.

Some solutions shared by the SAP Community members to retrieve the current logged in user information can be found here:

But like we all grow in our development skills, the technologies and features do too.

The SAP Approuter NPM Package was extended with a “User API Service”.

All required information and more about this service can be found here:

@sap/approuter – npm (npmjs.com)

This also means there is no need to describe this “Approuter User API Service” further in this blog post.

But we can build a very small and quick demo app together!

Let’s open the SAP Business Application studio!

 

Consuming the SAP Approuter – User API Service

Open a terminal in your BAS development workspace and execute the following command to initialize a basic multitarget application:

yo basic-multitarget-application

Name the project “approuterUserInformation”.

This generated your project, which is quite empty at the moment:

Enter the project by executing the following command and create an “approuter” directory and access it as well:

cd approuterUserInformation && mkdir approuter && cd approuter

Inside this “approuter” directory we execute the following command to initialize npm:

npm init

Just use the default values for the configuration of the command above.

Once generated add the “start” script inside your “package.json” file so it looks like this:

"start": "node node_modules/@sap/approuter/approuter.js"

Finally, we install the SAP Approuter NPM package by executing the following command:

npm i @sap/approuter

If I’m not mistaken the SAP Approuter User API Service is available since version “9.1.0”.

Create an “xs-app.json” file by executing the following command:

touch xs-app.json

Add the following configuration to it:

{
    "welcomeFile": "index.html",
    "authenticationMethod": "route",
    "routes": [
        {
            "source": "^/user-api(.*)",
            "target": "$1",
            "service": "sap-approuter-userapi"
        }
    ]
}

As you can see the route will consume the “sap-approuter-userapi” service to return the logged in user information. Do note the “authenticationMethod” property is set to “route” so authentication is enabled for the desired routes.

The “source” uses the following regex “”^/user-api(.*)” which should be completed in either one of the following ways to retrieve the user information:

  • /currentUser
  • /attributes

Both endpoints return firstName, lastName, email and name. While the “/currentUser” endpoint also returns the displayName.

Running the Approuter and requesting the endpoint in one of the two ways described above would not work.

It would return the following error:

“GET request to /user-api/currentUser completed with status 500 OAuth2 requires “clientid” option.”

The reason for that is because we are still missing an “xsuaa” service instance.

Login to Cloud Foundry via the Business Application Studio or by using the BAS terminal cf cli.

Next you create an “xsuaa” service instance via the BAS command pallet (CTRL + Shift + P) and you type “create a new service instance” (choose a name for the “xsuaa” service instance with the “application” service plan) or by using the cf cli on the terminal, or even via the SCP Cockpit.

Once created, you bind the “xsuaa” configuration via the command pallet “bind a service to locally run application”, choose your “approuter” directory as destination and you will see a “.env” file will be created. Rename the “.env” file to “default-env.json” and correct the JSON content. Or use the terminal achieve the same result.

You will need the “default-env.json” file holding your “xsuaa” service configuration to be able to perform authenticated requests.

Time to run your Approuter by executing the following command:

npm run start

Remove the “/index.html” part of the URL and type the following like configured in the Approuter:

/user-api/currentUser

As you can see you get the expected response:

{
  "firstname": "Dries",
  "lastname": "Van Vaerenbergh",
  "email": "myEmailAddress",
  "name": "myEmailAddress ",
  "displayName": "Dries Van Vaerenbergh (myEmailAddress)"
}

Now try the attributes URL-endpoint:

/user-api/attributes

Once more we receive the desired response from our Approuter its User API Service:

{
  "firstname": "Dries",
  "lastname": "Van Vaerenbergh",
  "email": "myEmailAddress ",
  "name": "myEmailAddress "
}

 

Wrap up

Like I mentioned before it was very easy to use the “userapi” on the NEO Environment, and we had some extra developments to achieve the same result in the Cloud Foundry Environment.

But now with this SAP Approuter upgrade we only need our “xsuaa” service instance and the right Approuter version and configuration, so we can easily consume the desired user information inside our applications.

I hope this can ease your developments and needs to retrieve the logged-on user information.

Best regards,

Dries Van Vaerenbergh

Assigned Tags

      34 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Yogananda Muthaiah
      Yogananda Muthaiah

      This is excellent, Thanks for sharing this info Dries Van Vaerenbergh

      Author's profile photo Dries Van Vaerenbergh
      Dries Van Vaerenbergh
      Blog Post Author

      Thanks a lot Yogananda!

      It's a pleasure to share!

      A really nice functionality of the SAP Approuter, it will really simplify the development process to retrieve the user information a lot.

      Best regards,

      Dries

      Author's profile photo Pieter Janssens
      Pieter Janssens

      Hi Dries,

       

      Thanks. This is a very useful addition to the @sap/approuter indeed!
      Have you tried running this locally with VCAP_SERVICES loaded for xsuaa via default-env.json? I'm getting a 503, while it's working without any issues in CF.

       

      Pieter

      Author's profile photo Dries Van Vaerenbergh
      Dries Van Vaerenbergh
      Blog Post Author

      Hi Pieter,

      Thanks a lot!

      I just tried it myself locally with VS Code and it seems to work.

      The only thing I changed was the xsuaa service instance. I recreated this instance and added the "http://localhost:5000" to the "redirect-uris" in the configuration steps of the xsuaa.

      Further my "package.json" file looks as follow with version "9.1.0" for the approuter:

      {
        "name": "approuter",
        "version": "1.0.0",
        "description": "",
        "main": "index.js",
        "scripts": {
          "test": "echo \"Error: no test specified\" && exit 1",
          "start": "node node_modules/@sap/approuter/approuter.js"
        },
        "author": "",
        "license": "ISC",
        "dependencies": {
          "@sap/approuter": "^9.1.0"
        }
      }
      

      And the "xs-app.json" file like this:

      {
          "welcomeFile": "index.html",
          "authenticationMethod": "route",
          "routes": [
              {
                  "source": "^/user-api(.*)",
                  "target": "$1",
                  "service": "sap-approuter-userapi"
              }
          ]
      }

      And the "default-env.json" file looks like this:

      {
          "VCAP_SERVICES": {
              "xsuaa": [
                  {
                      "name": "xsuaa-approuter-local",
                      "instance_name": "xsuaa-approuter-local",
                      "label": "xsuaa",
                      "tags": [
                          "xsuaa",
                          "endpoint:",
                          "org:",
                          "space:"
                      ],
                      "plan": "application",
                      "credentials": {
                          "apiurl": "",
                          "clientid": "",
                          "clientsecret": "",
                          "identityzone": "",
                          "identityzoneid": "",
                          "sburl": "",
                          "service_key_name": "",
                          "subaccountid": "",
                          "tenantid": "",
                          "tenantmode": "",
                          "uaadomain": "",
                          "url": "",
                          "verificationkey": "",
                          "xsappname": "",
                          "zoneid": ""
                      }
                  }
              ]
          }
      }

      Once my approuter is started I perform the following request and I retrieve the user information:

      http://localhost:5000/user-api/currentUser

      Did you perform all of these steps as well?

      Best regards,

      Dries

       

      Author's profile photo Pieter Janssens
      Pieter Janssens

      Hi Dries,

       

      Thanks for pointing out "redirect-uris". Unfortunately I'm not out of the woods yet.

      I removed all other routes, just to make sure there are no conflicts.

      I'm now seeing errors that indicate it's trying to resolve the path in a localDir, which is clearly not set.

      #2.0#2021 01 29 10:15:26:026#+01:00#ERROR#/Handler#####kki2mfuv####6YNMkqgp1QWBar-rm5zEmvihtzMVbkQy######kki2mfuv#PLAIN##GET request to //currentUser completed with status 404 ENOENT: no such file or directory, stat '/mnt/c/Users/pietejanssens/code/approuter/resources/currentUser'#

      I put a breakpoing in .node_modules/@sap/approuter/lib/middleware/user-api-middleware.js and when I go to 'http://localhost:5000/user-api/currentUser' it does break and I see that 'req.internalUrl.route.service' is undefined! 🤯

      I don't see any errors in my xs-app.json and the service is correctly set (otherwise it wouldn't work in CF either):

      {
          "welcomeFile": "/router/index.html",
          "authenticationMethod": "route",
          "logout": {
              "logoutEndpoint": "/do/logout"
          },
          "routes": [
      
              {
                  "source": "^/user-api(.*)",
                  "target": "$1",
                  "service": "sap-approuter-userapi"
              }
          ]
      }
      Author's profile photo Pieter Janssens
      Pieter Janssens

      After further investigation I see that this issue is introduced as soon as I put a

      html5-apps-repo in the VCAP_SERVICES of default-env.json. 🤔
      I'll create an incident for that.
      Author's profile photo Dries Van Vaerenbergh
      Dries Van Vaerenbergh
      Blog Post Author

      Hi Pieter,

      From your shared "xs-app.json" configuration and your last comment, I can tell you are adding this feature in an existing project or you are try out some extra stuff. When you try the example exactly like in the blogpost I believe it does work right?

      If you try to set the "welcomeFile" property to "index.html" and you remove the "html5-apps-repo" from your "default-env.json" file, does it work then?

      I also used the "html5-apps-repo" before in my VCAP_SERVICES in my default-env.json file. I believe that should still work actually, you can find an example here

      Timesheet Management with CAP & Trello ⏱️ – Setup the IDE & MTA Project #1 | SAP Blogs

      I suggest you try without the "html5-apps-repo" first and with the "index.html" as "welcomeFile" value.

      Hope that will get it up and running. 🙂

      Best regards,

      Dries

      Author's profile photo Pieter Janssens
      Pieter Janssens

      Hi Dries,

      Indeed, it works fine as soon as I remove the "html5-apps-repo" from the local env. I'll leave it out for now.

      Best regards,

      Pieter

      Author's profile photo Dries Van Vaerenbergh
      Dries Van Vaerenbergh
      Blog Post Author

      Hi Pieter,

      Good to hear it works that way!

      Curious as I am I tried it out myself using the "html5-apps-repo" and it works perfectly indeed once deployed to CF. I also experienced the same issue (using BAS) when trying to use the "html5-apps-repo" to run it locally (after binding it in the default-env.json file). I also get the "503 service unavailable" when requesting the user information in this case. using localDir it works fine when requesting the information from the ui5 app via the approuter. Maybe Marius Obert has an idea about this one? 🙂

      Still an amazing update to the SAP approuter and a handy to use service of course.

      Best regards,

      Dries

      Author's profile photo Marius Obert
      Marius Obert

      I have to admit you are already way deeper in this than I am 🙂

      I'd suggest opening a new question for this in the community so that the product team can pick it up.

      Author's profile photo Dries Van Vaerenbergh
      Dries Van Vaerenbergh
      Blog Post Author

      Thanks a lot Marius!

      Author's profile photo Pablo Costantini
      Pablo Costantini

      Did you do this with a HTML5 app Pieter Janssens ?

      Thanks.

      Author's profile photo Pieter Janssens
      Pieter Janssens

      SAP (Sergio):

      This flow will work if instead of using defaut-env.json you would set the VCAP_SERVICES as IDE environment variable. With this it is guaranteed that the node process environment is correctly populated before start.

      This is a limitation of providing environment variables via files. Currently there is no correction that we can provide.

      Root cause:

      1. During approuter startup DynamicRouting middleware is initialized if approuter is bound to html5 repo. This check returns false because xsenv module does not find default-env.json in the disk because the app. is not started yet, therefore the middleware is not initialized

      2. Later on, during path evaluation, binding to repo is evaluated again and it returns true, but this is too late because the DynamicRouting middleware was not loaded and this is a kind of inconsistent state.

      Author's profile photo Marius Obert
      Marius Obert

      "But we always find a solution for everything and very often they are shared on the SAP Community"

      **Mic drop**

      Author's profile photo Dries Van Vaerenbergh
      Dries Van Vaerenbergh
      Blog Post Author

      Haha nice one Marius Obert !

      I really like the way the Community shares its solutions and that we can all benefit from each others ideas and visions. Thanks to everyones contribution the circle of amazing ideas keeps going!

      So a big thanks to everyone for the solutions and inspiring ideas! 😃

      Author's profile photo Pablo Costantini
      Pablo Costantini

      Dries Van Vaerenbergh

      Is it posible to do this with a Cloud Foundry HTML5 app? (they didn't have an app router file.

      Thanks in advance.

      Author's profile photo Dries Van Vaerenbergh
      Dries Van Vaerenbergh
      Blog Post Author

      Hi Pablo,

      Thanks for your question.

      I am not sure if I understand your question correctly but if you mean an "xs-app.json" file by app router file, a Fiori/HTML Module contains an "xs-app.json" file as well.

      But by adding the route with the User API service to the Fiori Module its "xs-app.json" file, I do not believe this will work, since this User API service is an SAP Approuter feature.

      But when you generate a new project (for example via the wizard in the SAP BAS) you have to choose an approuter (standalone or managed) and thus you are able to implement such a scenario to consume the user information via the approuter.

      I hope this answers your question.

      Best regards,

      Dries

      Author's profile photo Ari Lulu
      Ari Lulu

      Hi Pablo,

      Yes. It should work both with xs-app.json on application level or on approuter level.

      It means that you will be able to use it also when working with managed approuter.

      Best Regards,

      Ari

      Author's profile photo Dries Van Vaerenbergh
      Dries Van Vaerenbergh
      Blog Post Author

      Hi Ari,

      Thanks for your answer!

      Implementing the following route on approuter level (xs-app.json) does work indeed (with xsuaa bound of course and authenticationMethod route):

      {
                  "source": "^/user-api(.*)",
                  "target": "$1",
                  "service": "sap-approuter-userapi"
              }

      But when using the exact same route and xsuaa service on application level the app won't start. I'm using the BAS with a basic UI5 app from template and a managed approuter.

      So I was not able to use the User API Service on the application level yet.

      Any Idea on this one? Did you experience a different result?

      Thanks in advance!

      Best regards,

      Dries

      Author's profile photo Ari Lulu
      Ari Lulu

      Hi Dries,

      You were too quick with your blog 🙂

      It will be supported in Managed Approuter next week.

      That's the reason Managed Approuter docs were not updated yet:

      https://help.sap.com/viewer/8c8e1958338140699bd4811b37b82ece/Cloud/en-US/c1b9d6facfc942e3bca664ae06387e9b.html

      Once it will be supported, also a release note will be published.

      Best Regards,
      Ari

      Author's profile photo Dries Van Vaerenbergh
      Dries Van Vaerenbergh
      Blog Post Author

      Hi Ari,

      Thanks for the information!

      Guess I will give it another try next week then! 🙂

      Best regards,

      Dries

      Author's profile photo Prasanna Jagadeesh
      Prasanna Jagadeesh

      Hi Dries,

      Very detailed blog. Thanks.

      It worked for me with the Managed app router. fyi, if you haven't tried yet 🙂

       

      Cheers,

      Prasanna

      Author's profile photo Dries Van Vaerenbergh
      Dries Van Vaerenbergh
      Blog Post Author

      Hi Prasanna,

      Thanks for the nice feedback!

      I did not try it out myself yet, but thanks a lot for letting me know!

      Really appreciate it!

      Best regards,

      Dries

      Author's profile photo Tia Ahuja
      Tia Ahuja

      Hello Prasana,

      I want to achieve this functionality with Fiori application. Could you guide me how were you able to use the user api?

      When I install the sap router, I am getting an error:

      Having said that, do i also need to include the change the start script to

      "start": "node node_modules/@sap/approuter/approuter.js"

      in package.json?

      Last, how do we read the user information in a controller or model?

      Appreciate your help.

      Thank you.

      Author's profile photo Akhil Raj Kizhakkan
      Akhil Raj Kizhakkan

      Hi Ari Lulu ,

      Trying to implement this currentuser api in our HTML5 application that only uses managed app router.

      Could not find a relevant documentation/blog that explains the changes required. Could you please provide some info ?

       

      Best regards,
      Akhil

      Author's profile photo Karthikeyan Sathyanarayanamurthy
      Karthikeyan Sathyanarayanamurthy

      Hi Dries Van Vaerenbergh ,

      Thanks for sharing this as we wanted to get the User information for our Application. I created a new App as mentioned by you and everything works fine using the Approuter.

      But, I tried to do something similar with my existing App and I ended up getting an error.

      VError: xs-app.json/routes/0: Format validation failed (A route requires access to sap-approuter-userapi service but the service is not bound.)

       

      I have created the XSUAA service and have bounded it locally. Did you or anyone come across such an error ? Any light on this would be really helpful.

       

      Thanks,

      Karthik

      Author's profile photo Dries Van Vaerenbergh
      Dries Van Vaerenbergh
      Blog Post Author

      Hi Karthik,

      Thanks for your comment and feedback! 🙂

      Since it worked in the demo you recreated, I was wondering if it could be that your approuter version in your existing app might be lower than “9.1.0”? The user-api service is available as of version “9.1.0” if I'm not mistaken.

      Could that be the issue?

      Best regards,

      Dries

       

      Author's profile photo Karthikeyan Sathyanarayanamurthy
      Karthikeyan Sathyanarayanamurthy

      Hi Dries,

      Yes, I thought about it. But wasn't sure how to do I add the newest version to my app router. One option I tried was to remove the node modules and install it again.

      Regards,

      Karthik

      Author's profile photo Sumedh Agarwal
      Sumedh Agarwal

      Hi Dries,

       

      I have an UI5 app in cloud foundry where i want all the user details of the logged-in user. Previously i could get the basic details like name, and email. etc using the solution given in the following link: -

      https://blogs.sap.com/2020/06/04/retrieve-logged-in-user-details-in-cloud-foundry-using-web-ide/

       

       

      But as part of further developments i want some additional/all details as well including country, relationship to SAP etc.

      Can you help me with this. Please consider urgent.

      Thanks in advance!!

      Author's profile photo Isaac Perez
      Isaac Perez

      Greetings, Mr. Dries Van Vaerenbergh.

      I found your publication very good. Apart very concise.

      I wonder if it works (I mean the /user-api/currentUser and /user-api/attributes paths) once the application is deployed to Cloud Foundry or is it something that only works for testing within SAP BAS.

      Apologies in advance for the ignorance reflected in my question.

      Author's profile photo Ramana Reddy Reddy Moole
      Ramana Reddy Reddy Moole

      Thank you for the question. I have the same question after going throuh the blog.

      Author's profile photo Likith Prakash
      Likith Prakash

      Is there a way where we can get the user ID information of the logged in user?

      Author's profile photo Dries Van Vaerenbergh
      Dries Van Vaerenbergh
      Blog Post Author

      Hi Likith Prakash,

      The approuter npm documentation states the following:

      "Note that the "name" property is the user ID in the identity provider, which in many cases is also the email address."

      Hopefully this helps and answers your question.

      Best regards,

      Dries

      Author's profile photo Arnab Datta
      Arnab Datta

      Hi,

      Thanks for this tutorial. But calling the user api is not returning the custom role collection assigned to the user. How can I get the role collection assigned to user in BTP. Its just returning the below json. No custom role assigned to the user returned in scopes[]. Any idea?

      {"firstname": "XXXX","lastname": "YYYY: "aaaa@xyz.xom","name": "XXXX","scopes": ["openid","uaa.user"],"displayName": "XXXX YYYY"}