views:

72

answers:

1

I have a controller dealing with sending SMS Messages, and it's set up as a default resource. Now, business requirements have changed and we want to offer the user three different ways of sending the message:

  1. To everybody on their contact list
  2. To a segmented portion of their contact list (predefined)
  3. To individual contacts that they can choose

In addition, there are two ways they can send an SMS Message: Premium (via an sms gateway) or Standard (via SMTP). So there are essentially six different ways to send a message (three for premium, three for standard).

The requirements state that the three options above need to be presented in a "wizard-like" format, as three radio button choices and then a submit button which displays the appropriate form and list:

  • If option 1 (send to everyone) then just display a textbox for sending the SMS
  • If option 2 (send to a segment) then display a list of segments as radio buttons
  • If option 3 (send to specific) then display a searchable/sortable list of all contacts with checkboxes next to their names, and on submit select everyone checked to send.

The issue I'm running into is how to make this fit the RESTful conventions imposed by the resource. Each of these use cases is technically only one action (well, two since it would correspond to new/create) but it looks like there needs to be an inordinate amount of logic in the action then, and rather messy as well (switch statement or similar).

Is there a better way do to this?

+1  A: 

I would consider "the simplest thing that works" approach first. Different params processing and setting up several delivery methods looks like something that cannot be easily wrapped into a pair of "new" and "create" actions.

Without knowing all the details, my first recommendation would be just to implement actions like "choose_contacts", "send_to_contacts" and "choose_segments", "send_to_segments" which either prepare the data for these use cases and render their own templates, or process incoming data and handle possible errors. Then "new" action will just dispatch processing to an appropriate action based on selected option, while "create" action won't longer be needed (or you can re-use it for sending a single message). I bet the code for sending a single message (or a set of messages) is in model anyway, so you'll just have to call it with correct arguments once you processed your form data in a reasonable way.

Benefits of this approach:

  1. It reads more naturally by someone who will maintain your code later, as it clearly differentiates available options;

  2. You'll have more flexibility processing an input params and handling errors from different forms, as you'll know which erroneous state to render as a response, without carrying additional data from the form. Segments and contacts probably require different processing, aren't they?

  3. If you use some kind of a performance management application (such as NewRelic), you'll see if one of certain delivery processing actions has any performance problems much faster than in case of a general SMSDelivery#create action;

I had the similar situation with "inviting/finding friends via uploading/searching contacts" process, and the given approach worked really well for me. Overall, REST is a great convention, but trying to squeeze a lot of business logic into a CRUD sometimes is not perfect and error-prone. YMMV, I would just suggest to keep logic clear and easy to read, modifying existing conventions if you're not feeling flexible enough with them.

Oleg Shaldybin