I'm writing an API in Rails which retrieves prices for a package from multiple carriers. A package is universally described in terms of dimensions, weight, address-from and address-to. Each carrier would have specific details (FedEx: account-number, package-options; USPS: machinability, presorting; UPS: notification-details, etc.). I'm still deciding if I should store the price locally or retrieve them from the official APIs.
My first question is about the price resource. I do have a Price model, but it's not inheriting from ActiveRecord since I don't have a prices table. I'm thinking that my URL would look like /api/v1/prices and it would take a payload like { "length" : 1.0, "address_from" : ... }
. Should this be a POST or a GET? I'm guessing a GET since I'm not actually creating a resource, but I'm not sure.
My second question is about the payload. Should I nest the carrier specific data? In other words, which way looks more correct (from a RESTful point of view and from an ease-of-use point of view)?
Option 1:
{ "length" : 1.0, ..., "carrier" : { "name" : "FedEx", "account_number" : "123ABC", "package_options" : "XXX", ... } }
Option 2:
{ "length" : 1.0, ..., "carrier" : "FedEx", "fedex_account_number" : "123ABC", "fedex_package_options" : "XXX", ... }
If it's Option 1, should I create some kind of resource nesting and should I change my URL construct?
I'm still deciding if I should store the price locally or retrieve them from the official APIs.
Really good question. What if the price changes in the future? Does your app depend on the price at the time when the API call was made? If so, you should definitely store it locally as the price may vary from API call to API call. If in doubt, I would store this value so you have a paper trail for auditing purposes later.
I agree that /api/v1/prices
should get a GET request as you're not creating a resource, either on your DB or on a remote service/API. But is this a singular or plural resource? If it's singular you should consider using /api/v1/price
. Whether you make the price id part of the url or as an extra param is up to you.
I prefer the style of Option 1 because the JSON format preserves the underlying model relationships. This not makes it easier to use, and also "self-describing" in that the format of the data communicates it's structure as well. It also doesn't require parsing the JSON keys.