Phoenix controller actions - how best to perform an action that doesn’t quite fit in the RESTful model?

Hi all!

Pretty newbie question; it’s my first time using a full stack web framework to do frontend and I was wondering what should be the approach in Phoenix to perform an action that doesn’t quite fit in the RESTful model (as I understand it at the moment).

As an example, say I have a dashboard for a blog and “/” would list all posts. I want to have a button there that when pressed would call a function in the backend that would query all posts and capitalize all titles and would return the number of updated entries (still at “/”). Now, this is not an edit or update of any specific post or even specific group of posts so I was wondering how should I conceptualize this.

Apologies if the question is difficult to follow, I probably misusing terminology here :grimacing:

Hi ! ^^
Following your example I would say that that the request to “/” url that just list all post is a get request.

get “/”, PostController, :index

If you want your action to be still requested at “/”, you will need to use another method than get for the request, since the index action of the PostController will always match a get request at “/”.

In fact Even though there was no route defined as a get request at that path, I don’t find it really convenient to use the get method for that. For example to delete a resource or upvote a post we don’t want to use just a get request. Copy pasting the path in the browser adress bar should not be sufficient to trigger this kind of action. We want a button in a specific context to send that request.

So if we eliminate the get method, we are left with 4 others: post, put, patch, delete.

If you opt for the post :

post “/”, SomeController, :some_action

You will just put your button inside a form that will have “/” as action and post as method.

For put, patch, delete a simple link in your template with the right method will be sufficient. According to what you want you will chose on of them. For your specific example I would take either post or patch.

patch “/”, SomeController, :some_action

And in the template:

link(“Do some action”, to: “/”, method: :patch)

Since I started to learn some LiveView recently, I can add that if your button is in a live view a lot of all these considerations will be simplified. You could just pass an event through the socket and do whatever you want without the hassle of all those protocols. :slight_smile:

1 Like

That’s exactly what I was looking for, thank you for the detailed answer!

This also made me curious about LiveView as well, I guess that’s good timing! :slight_smile:

1 Like