We are building our first Coldbox REST API and we're far enough along that we are starting to want to consume some of what we've written from elsewhere in our app. We ran into this scenario – really an architecture question – and suggested filing a ticket so that could weigh in.
Pre-API, our handlers would submit requests to our service layer which would take care of the business logic and return a custom response object.
Post-API, we've replaced our custom response object with the Coldbox Response.cfc and we're trying to enforce this request/response model (e.g. HTTP status codes, messages) everywhere we can. Say we have an endpoint `/api/foo` and we've written a simple `delete` resource that looks up the `foo` in question and deletes it. No service layer calls – API validates the request and deletes accordingly.
Elsewhere on our app, we have some CRUD pages that manage `foo`, and one of those pages wants to delete a `foo`. "We'll use our new API," we think, "and pretend like we're those cool developers who write such a great API that it does everything for everybody."
Since these CRUD pages are drawing and processing forms, they have their own `fooHandler` to take care of this. When it gets a request to delete a `foo`, we had it do this, where v1 is the v1 sub-module of our API:
This breaks if we use `allowedMethods` because the original request to `fooHandler` is a POST rather than a DELETE.
Brad rightly asked why we would be consuming a REST resource from CFML – why not just use a service layer? So that's part of my question, too – we could easily refactor the API to just hit a service layer, meaning our internal app would continue to use a service layer as it always has rather than using the API. This seems to me an emphasis more on the 'I' of 'API' in that it's just interfacing with something, but I wonder whether there is utility in baking logic into the API and removing (some) of the need for a service layer entirely.
This does seem unorthodox, but then we can version the API more easily than we can version a service layer. If this is an accepted architecture, probably runEvent should ignore allowedMethods. If it's not a good idea, we'll just go back to using our service layer ... but that doesn't feel as HMVC-y for some reason.
What do you think?
I think the three questions that come out that I'd like answered are:
should REST actions not be reusable via runEvent()?
should runevent() allow you to override the HTTP method?
should internal event calls not even enforce the HTTP method since they weren't a direct product of an HTTP call in the first place?
Can you give Samuel any feedback on this?
I have been pondering on this ticket for a while, just have not answered until now.
My gut feeling is that if I am within the application boundaries, it does NOT make sense to validate HTTP methods yet again for internal run event calls.
The HTTP security is usually just done at the *default* incoming event. So I am going to go with that if we are using a *runEvent()* then allowed methods are ignored.