4

I have a Rails API backend and a ReactJS frontend. My backend sends custom emails that often have confirmation-like links (like email confirmation)

Should the confirmation links point to my backend directly, or should they rather load the frontend first and then make an API call to the backend?

The two alternatives I'm thinking of are:

1 - The email confirmation link hits directly

backend.example.com/email_confirmations/:confirmation_token, which then redirects to a specific success (error) page frontend.example.com/email_confirmation/success(/failure) on my frontend.

On the backend I would only need a Metal controller with minimum modules to perform redirection to the frontend app, the controller is always responding with redirects). If further actions need to be taken from the frontend, they'll hit a different API Endpoint

2 - The email confirmation links opens up my frontend at

frontend.example.com/email_confirmations/:confirmation_token that triggers an API request to backend.example.com/email_confirmations/:confirmation_token.

Then my (Json:api) backend makes a jsonapi-compliant response with a Rails APIController.

What are you doing in practice?

I decided to opt in for the first scenario but maybe systematically calling/loading the frontend first makes more sense?

How do you wire backend/frontend in those scenarios?

I have currently implemented a very simple (Metal) Controller that would just process the incoming parameters perform redirections only to the frontend. I was hoping to define "url helpers" that would point to my frontend like so:

namespace :email_redirection do 
    # Controller that gets hit by email confirmation links in scenario #1
    resources :confirmations
end

namespace :frontend do
    frontend_root = Rails.configuration.frontend_host_with_http_and_port

    scope frontend_root do
      # Generation of URL Helpers for the frontend app
      resources :confirmations, only: [] do
        get 'successful'
        get 'unsuccessful'
      end
    end
end

And my confirmation controller would be like

class EmailRedirection::ConfirmationsController
  def index
    svc = MyConfirmationService.new(token: params[:confirmation_token])
    if svc.confirm
      redirect_to(
        frontend_successful_confirmation_url,
        email: svc.confirmable.email
      )
      else
        redirect_to(frontend_unsuccessful_confirmation_url)
      end
    end
  end

I'm getting several error and I believe maybe the url helpers are not useable with different host/port... (or I have to pass them explicitely to each call)

How can I handle that ? And if 1. is a good choice, what would be the redirection codes you'd send on success/failure (since they can only be 3xx) ?

Both solutions involve quite some wiring between the backend/frontend and I'm not sure how to best wire things up.

Note : my models use devise but because devise isn't so great with APIs/etc. I'm using my own ConfirmationService that also handles some side-effects. I don't consider Devise to be relevant here

Creating a rails route to an external URL

James
  • 5,635
  • 2
  • 33
  • 44
Cyril Duchon-Doris
  • 12,964
  • 9
  • 77
  • 164

0 Answers0