Website based on REST in ColdFusion

2020-07-11 06:57发布

问题:

My company is about to redesign a big project from scratch. We are currently thinking about how to implement data providers. I used to integrate some webservices in the last few months and pretty much like handling data this way. So I was thinking about a RESTful design. We will be using ColdFusion 10 that comes with REST support, but I actually don't like the component structure required for it.

The biggest advantage is probably that we'll be able to use REST to provide data for all our platforms, that is: website, mobile website and iOS/Android app. My security approach would be as follow: Public data can be accessed by anyone (obviously). Private data can be accessed with BasicAuth only. Using BasicAuth also allows us to have user roles with different access levels. The authorization will be implicit and based on the session/login.

<!--- server-side example to request customer information (private data, BasicAuth required) --->
<cfset requestedID = 123>
<cfhttp url="/customer/#requestedID#" method="get" username="#APPLICATION.REST_SYSTEMUSER#" password="#APPLICATION.REST_SYSTEMUSER_PW#">
    <cfhttpparam type="url" name="includeAddresses" value="true">
</cfhttp>

<!--- successful response in JSON --->
{
    "ID": 123,
    "FirstName": "John",
    "LastName": "Doe",
    "Birthday": "1970-01-01",
    "BillingAddress": {
        "Receiver": "John Doe",
        "Street": {
            "Name": "Main Street",
            "Number": "13",
            "Addition": ""
        }
        "City": {
            "ZipCode": "AB-123",
            "Name": "Sampletown",
            "District": ""
        }
    },
    "ShippingAddresses": [
    ]
}

<!--- deserialize JSON and build an object to use server-side (the constructor wraps the data and adds functions to it) --->
<cfset customerJSON = deserializeJSON(CFHTTP.FileContent)>
<cfset customer = createObject("component", "Customer").init(customerJSON)>

Here are the questions that came to my mind:

  1. Is it smart to use this general REST approach for everything on every single page? (Is it smart to use REST on websites to begin with?)
  2. Do local HTTP requests impact performance and slow down page loading?
  3. Is BasicAuth sufficient to protect the data? (I would just add minor security features such as request-spam-protection to it)
  4. Is it best to avoid having dependencies within the webservice like /customer/ accessing /address/ to receive its data?

On some of the other (older) website we have file based data providers (includes and components that take care of database access etc.), but we experienced several issues with the more complex pages (such as a checkout process) like name conflicts through includes, intransparent and heavy components, mixing up model/view/controller elements etc.

回答1:

Here's my answers, based on the research I've done recently. My company is looking at new product development, so I've been asking a lot of the same questions as yourself. We're also very attracted by the notion of a REST API being not only something that enables the front-end but in it also becoming an integration point for other applications. We've maintained a separate API for other products and it's all too easy for it to loose sync with the main App if you're not careful.

  1. Is it smart to use the REST/Single-Page approach? It certainly can be. A number of large sites work like this. What does seem to be common is a hybrid approach where the server may generate the HTML for the initial page, perhaps with 10 products shown), but moving to the next 10 products will be via a RESTful call, with client-side rendering. This probably gets you the best possible customer experience, but at the slight cost of building two different templates (the server-side one, as well as the client-side one). Depending on how your site works and who uses it, this may or may not be needed. For example, GMail is a single-page app, but it's an app and you tolerate the couple of seconds it spends showing you a loading bar, whereas running a retail site, this kind of lag may not be acceptable.

  2. Do local requests slow down loading? Do you mean having your website making REST calls to get it's data, rather that going straight to database? In which case, it will add some latency, as there's an extra network hop involved, but in a well set up system and deployment, I'd think that lag may be manageable.

  3. HTTP-basic. I'd only consider it over HTTPS. It's just not secure enough over HTTP. This is covered in the presentation I link to below.

  4. Dependent data. I was wondering about that too. What I round very helpful was watching the presentation from StormPath, which covered a lot of concerns and good practices when implementing a RESTful API. They cover an approach for linking the data (following HATEOAS principles) but also entity expansion, so a GET to /customers/ID123?expand=address would return a representation of the customer, but with their Address embedded, which is a nice way of avoiding multiple round-trips to get all the data you need.

Regarding CF10's REST support. I looked at it and wasn't all that keen on how it worked. I may have misunderstood it, but the REST app seemed to be very separated from any kind of regular app you were trying to hybrid alongside. The Railo implementation seemed pretty similar, but with slightly different niggles. Certainly, building a REST app which worked on both seemed pretty tricky. Have you looked at Taffy at all? I've not, but would be interested in how it works.

Because REST is an architectural style, rather than a strict standard, there's a lot of latitude for exactly how you implement things and a lot of scope for debate/argument on the 'best' approach



回答2:

I recently came across a project called Taffy which is a framework for writing REST APIs in ColdFusion. It works with CF8-10 and Railo. I'm very impressed with how it structures the code and how easy it becomes to write each of the REST end points. You may wish to look into that project as well for the back end.



回答3:

Is it smart to use this general REST approach for everything on every single page? (Is it smart to use REST on websites to begin with?)

I'm not sure, but one big thing that bothers me is how REST calls in CF10 bypass the onError error handler. Here's the bug report that has been marked Fixed, but WHO KNOWS WHEN WE'LL GET IT really. CF11? I don't know, ask Adobe.

This really sucks as one may never know what exactly went wrong other than getting a 5xx error code on the client side.

Do local HTTP requests impact performance and slow down page loading?

Sure it does. I think it would be better if both web & RESTful API fronts invoke the same method in the Service layer.

Is BasicAuth sufficient to protect the data? (I would just add minor security features such as request-spam-protection to it)

Usually yes, if it is HTTPS. Depends what is "sufficient".

Is it best to avoid having dependencies within the webservice like /customer/ accessing /address/ to receive its data?

Agree with barnyr, please read his answer.

Lastly, just want to point out that other than CF10's official implementation, there are frameworks like Taffy or ColdBox that can deal with RESTful APIs without CF10.

Also, check out What can CF10 RESTful API do that Coldbox RESTful API cannot do? And vise versa?