Proper way to make a POST request?

What is the proper way to make a post request? Several people have asked this in the past, but the answer still seems unclear. I want a SideNav menu item that starts a Stripe checkout session. I could change it to a GET request, but a POST request is more appropriate.

I suppose I could just inject an HTML form, but I suspect there is a Vaadin way to do this.

private SideNav createNavigation() {
        SideNav nav = new SideNav();

        List<MenuEntry> menuEntries = MenuConfiguration.getMenuEntries();
        menuEntries.forEach(entry -> {
            if (entry.icon() != null) {
                nav.addItem(new SideNavItem(entry.title(), entry.path(), new SvgIcon(entry.icon())));
            } else {
                nav.addItem(new SideNavItem(entry.title(), entry.path()));
            }
        });

        SideNavItem addCreditNavItem = new SideNavItem("Add Credit", "create-checkout-session");
        nav.addItem(addCreditNavItem);

        return nav;
    }
@Controller
@RequestMapping("/create-checkout-session")
public class CreateCheckoutSessionController {

    private final CheckoutSessionService checkoutSessionService;

    public CreateCheckoutSessionController(CheckoutSessionService checkoutSessionService) {
        this.checkoutSessionService = checkoutSessionService;
    }

    @PostMapping
    public RedirectView createCheckoutSession() {
        try {
            String sessionUrl = checkoutSessionService.createCheckoutSession();
            return new RedirectView(sessionUrl);
        } catch (Exception e) {
            Broadcaster.broadcast("Failed to create a Stripe session: " + e.getMessage());
            return new RedirectView("");
        }
    }
}
1 Like

I think your way is fine (although it might need a security review). Vaadin the framework abstracts the network communication layer away from the application developer, so there’s no correct “Vaadin” way to send a specific type of request. In my opinion, it’s best to treat any integrations like that as fully separate applications.

2 Likes

Why do you need a Post Request if your creation method is already available as callable service?

  • Create a dummy view to be placed in your navigation
  • Inject your service into the view
  • In the before enter listener - execute your service call
  • Redirect the user to the page returned by your service
5 Likes

Is this what you were describing?

@PermitAll
@PageTitle("Add Credit")
@Route("create-checkout-session")
@Menu(order = 2, icon = LineAwesomeIconUrl.CREDIT_CARD_SOLID)
@Uses(Icon.class)
public class CreateCheckoutSessionView implements BeforeEnterObserver {
    private final CheckoutSessionService checkoutSessionService;

    public CreateCheckoutSessionView(CheckoutSessionService checkoutSessionService) {
        this.checkoutSessionService = checkoutSessionService;
    }

    @Override
    public void beforeEnter(BeforeEnterEvent event) {
        try {
            String sessionUrl = checkoutSessionService.createCheckoutSession();
            UI.getCurrent().getPage().open(sessionUrl, "_self");
        } catch (Exception e) {
            Broadcaster.broadcast("Failed to create a Stripe session: " + e.getMessage());
        }
    }
}

Yes, except this line. Take a look at the event in your method - it has a lot of methods :wink:

1 Like

Thanks! And, I don’t understand. I did look at event.forwardTo() and event.forwardToUrl, but I couldn’t find any information to explain whether those were better or more appropriate for my use case.

Would you be willing to explain?

re: https://vaadin.com/docs/latest/flow/routing/lifecycle#forwarding

Methods used on the event are passed to the “Navigation lifecircle” - which let’s Vaadin properly (as designed) handle additional navigations / redirect within the current navigation. With UI::getCurrent… you are bypassing the “official” way by creating a completely new navigation - imho it feels “dirty”

1 Like

In the end I couldn’t get event.forwardTo(sessionUrl); to work. According to chatGPT:

event.forwardTo() doesn’t work for external URLs because it expects a Vaadin route that is internally registered in your application.

oh, never mind. event.forwardToUrl(sessionUrl); works. :)

1 Like