Portal module example

Hello Team,

I study the opportunity to implement a portal module to my Cuba app.
I took into account this example https://github.com/cuba-platform/sample-portal.

From what I see is necessary to create custom user interfaces which are not directly part of the CUBA application. Instead it can be deployed independently and communicate with the platform middleware.
With Spring MVC you could either create HTTP based APIs (if you don’t want to use the generic REST API) or HTML based user interfaces.
1.What is the difference between these two approaches?
2. Also I want to know if there is any limitation here (jsp, freemaker, angular, vaadin+polymer etc)?

As a test I use add-on REST in order to create a rest-service.xml. Something like that:

<services xmlns="http://schemas.haulmont.com/cuba/rest-services-v2.xsd">
    <service name="myapp_SomeService">
        <method name="sum">
            <param name="number1"/>
            <param name="number2"/>
        </method>

Everything is ok I made some GET request from Postman - it works.
3. What is this REST-API - rest-service? Some kind of Cuba server?

On the other hand I saw that all these POST, GET request are made (in the sample-portal example) from main.js - javascript.
However in the portal folder there is a Controller as well.
4. It’s not quite clear for me what is the difference between javascript (main.js) request and Controller request (from portal)? Could you provide more details pls? Can I make all requests from portal controller (and replace the whole Angular folders with a HTML file ?)
5. How did you made the Angular interface? You made it in Angular and after that you copied the folders in portal/web? Also I saw that you use polymer. Please explain the process a little bit.

Sorry for my large question but I think that is an important subject.

Best Regards,
-n

Hi,

I believe this example might be a bit complex for a beginner. The attached example (which is simpler) provides a couple of pages to view and edit sessions and shows the custom OAuth2-protected REST API. You can find sessions that will be conducted by a particular speaker by invoking the API at the URL (as an example): http://localhost:8080/app-portal/rest/api/sessions/find?email=john.doe@sessions.com

Here is the attachment: session-planner.zip (113.6 KB)

The main thing that you need to remember - CUBA Portal is basically a Spring MVC application that can use all services provided by the CUBA Core module including DataManager, Email sender, FileStorageAPI etc. It is the same as working with the CUBA Web module, but using Web UI framework like Thymeleaf instead of the Generic UI.

The good thing about Portal module is its flexibility. You can implement the UI with any framework you like, use CSS, JS and all the tools developed for front-end development.
The same is about custom REST controllers that you can introduce in the Portal module. In contrast to Generic REST, you can use (almost) any URL for publishing your service and pass any parameters. In addition to this, you can use all HTTP methods like PUT or DELETE in your REST API. You can have a look at Spring Docs to learn more.

The other side of flexibility is that you need to write a bit more code to achieve your goals. In the case of Generic UI working with data from the UI happens “automatically”, but in the case of custom HTML UI you need to implement it by yourself.

Please have a look at the following classes in the example:
com.company.sessionplanner.portal.rest.SessionsController - custom REST API that delegates calls to the SessionsService.
com.company.sessionplanner.portal.controllers.SessionsWebController - WEB UI controller that manages pages flow and handles web forms data submission.

Answering to your questions:

You can use any web UI framework that Spring MVC supports. You can use JSPs, freemaker templates, vaadin, etc.

The Angular application invokes REST API from JS programmatically.

REST services can be invoked either from the HTML UI or from Javascript programmatically like in the example.

Controller in main.js and in in Java code serve the same function - route requests to a proper service. In case of Javascript it is a REST service invocation, and in case of Java - injected Java service. Yes, you can get rid of JS Angular application completely and use only Java controllers and HTML UI.

Personally I don’t know how it was implemented in the first place :slight_smile: I’d probably create the Angular app as a complete separate project and don’t even copy it to the CUBA app codebase. I’d suggest you to have a look at our frontend client documentation. This is the recommended approach if you decide to develop a JS-based client UI.

Hello Andrey,

I encounter " unable to find user cuba" exception (when I tried to create HSQLB database). I switched to Postgres database (however I replaced cuba user with postgres and sessionplanner-dP3vEvcey with sessionplaner database) but now I have this error (attached).
Error.txt (13.8 KB)

image

Seems that MailNotificationService is missing. Can you add it, please.

Thank you!

Yes, I forgot to mention that you need to enable a profile in your startup configuration, my bad.

You can:

  1. Enable profiles by using -Dspring.profiles.active=dev,service in your startup configuration.

OR

  1. Delete services descriptions from spring.xml in core module:
    <beans profile="dev">
        <bean name="sessionplanner_MailNotificationService" class="com.company.sessionplanner.service.DevMailNotificationServiceBean"/>
    </beans>

    <beans profile="prod">
        <bean name="sessionplanner_MailNotificationService" class="com.company.sessionplanner.service.ProdMailNotificationServiceBean"/>
    </beans>
  1. Delete ProdMailNotificationServiceBean and annotate DevMailNotificationServiceBean with
@Service(MailNotificationService.NAME)

Hi,

Actually I didn’t manage to find where should I put this line: -Dspring.profiles.active=dev,service.
However I aded in web.xml

<context-param>
        <param-name>spring.profiles.active</param-name>
        <param-value>dev</param-value>
    </context-param>

and I enabled

@Profile("dev")
@Service(MailNotificationService.NAME)

Everithing works fine.

I have to ask you: why is necesarry to have two Service profiles: one for dev another one for production?
I saw that for production you added these lines:

        String caption = "Session schedule has changed!";
        String body = String.format("For session %s new time is: %s", session.getTopic(), session.getStartDate());
        try {
            emailerAPI.sendEmail(EmailInfoBuilder.create(session.getSpeaker().getEmail(), caption, body).build());
        } catch (EmailException e) {
            log.error(e.getMessage(), e);
        }

Thank you!

It was just another sample, I forgot to remove it.

Ok, understood this. But what is the idea with these profiles? Generally speaking, why for dev could be different?

Hope you read about profiles. You may need different service implementations depending on the environment. The typical example - file storage. You can use local file storage in the dev environment, but for the prod, you may need cloud-based storage, especially when you use clustered configuration.

Thank you! Now is clear.
However I have the next questions (sorry if I bother you but I need to understand):

In portal I have two kinds of controllers:

  • SessionControllers that send request to Cuba rest-services.xml.
  • SessionWebController that access data directly (through dataManager).
  1. When I used Postman (with REST API example) before to make a Get I used Post in order to authenticate. Where is performed here the authentication between Portal and Middleware?
  2. Coud I get rid of REST API SessionService and replace it whith another controler from Portal? Or is mandatory to add / use REST API (rest-services.xml) from Cuba Marketplace? What is the main difference between these two approaches?
  3. Is there any way to debug these Get/ Post requests (classic from Idea breakpoints - or should I received some json(s) file to a particular address?

Thank you!
-n

Nope, you got it wrong. You can invoke any service here, including DataManager. It has nothing to do with the service publication via REST API add-on. The Add-on is used to simplify service publishing, so you don’t create controllers like SessionController manually.

Nope, this is not REST API controller, but web controller, that handles “ordinal” HTTP requests. Just have a look at the Spring MVC documentation. And you can inject any service here, including SessionService.

Just have a look at files portal-security-spring.xml and rest-dispatcher-spring.xml. They contain a security configuration for different path patterns.

Yes, you can get rid of the REST API add-on and still create REST controllers. The difference is the flexibility and the amount of code you need to write in order to publish your functionality via REST. See my previous posts in the same thread.

Just an ordinal built-in debugger should be enough. If you want to capture more traffic, use an external HTTP debugger like Fiddler.

You made my day. I will study your answers.
However what is your opinion: is it possible to create proffesional pages with Thymeleaf or is used especialy for demo / edu projects?
Is it better to use Vue or React in order to create UI?

Thymeleaf is a production-class framework, so you can create any UI with it. In fact, it all depends on your HTML/CSS/JS skills. It’s up to you to decide which framework you want to use. It depends on your skills and application use cases. If you plan that in most cases users will use a web browser to work with the application, you can create the UI using Thymeleaf and use an adaptive layout to resize the UI for different screen sizes.
If you plan to implement native mobile applications, then you’ll need REST API anyway, therefore you may consider using a JS framework. For CUBA, you can generate a basic ReactJS application even without ReactJS knowledge. But you’ll have to learn Typescript/Javascript anyway if you deal with web UI.

I have already generated a React Cuba frontend UI and looks nice. However does’t take all elements from my Browser/Edit view and I suppose that I have to add them manually and connect them with Cuba back-end logic.
How can I do that? Is the same approach with REST API? Is there a git example? Where shoul I place controllers?
However in this case what is the difference between a Cuba portal and a Cuba Front application? I imagine that both can be made with React (for instance).
I saw also that Cuba Front app run on 3000 port and Portal on 8000/app-portal…
Nevertheless most of new generated file have .ts extension (video stream). Is this normal?

Created a new topic: