How to organize endpoints when using FeathersJS's seemingly restrictive api methods? - express

I'm trying to figure out if FeathersJS suits my needs. I have looked at several examples and use cases. FeathersJS uses a set of request methods : find, get, create, update, patch and delete. No other methods let alone custom methods can be implemented and used, as confirmed on this other SO post..
Let's imagine this application where users can save their app settings. Careless of following method conventions, I would create an endpoint describing the action that is performed by the user. In this case, we could have, for instance: /saveSettings. Knowing there won't be any setting-finding, -creation, -updating (only some -patching) or -deleting. I might also need a /getSettings route.
My question is: can every action be reduced down to these request methods? To me, these actions are strongly bound to a specific collection/model. Sometimes, we need to create actions that are not bound to a single collection and could potentially interact with more than one collection/model.
For this example, I'm guessing it would be translated in FeathersJS with a service named Setting which would hold two methods: get() and a patch().
If that is the correct approach, it looks to me as if this solution is more server-oriented than client-oriented in the sense that we have to know, client-side, what underlying collection is going to get changed or affected. It feels like we are losing some level of freedom by not having some kind of routing between endpoints and services (like we have in vanilla ExpressJS).
Here's another example: I have a game character that can skill-up. When the user decides to skill-up a particular skill, a request is sent to the server. This endpoint can look like POST: /skillUp What would it be in FeathersJS? by implementing SkillUpService#create?
I hope you get the issue I'm trying to highlight here. Do you have some ideas to share or recommendations on how to organize the API in this particular framework?

I'm not an expert of featherJs, but if you build your database and models with a good logic,
these methods are all you need :
for the settings example, saveSettings corresponds to setting.patch({options}) so to the route settings/:id?options (method PATCH) since the user already has some default settings (created whith the user). getSetting would correspond to setting.find(query)
To create the user AND the settings, I guess you have a method to call setting.create({defaultOptions}) when the user CREATE route is called. This would be the right way.
for the skillUp route, depends on the conception of your database, but I guess it would be something like a table that gives you the level/skills/character, so you need a service for this specific table and to call skillLevel.patch({character, level})

In addition to the correct answer that #gui3 has already given, it is probably worth pointing out that Feathers is intentionally restricting in order to help you create RESTful APIs which focus on resources (data) and a known set of methods you can execute on them.
Aside from the answer you linked, this is also explained in more detail in the FAQ and an introduction to REST API design and why Feathers does what it does can be found in this article: Design patterns for modern web APIs. These are best practises that helped scale the internet (specifically the HTTP protocol) to what it is today and can work really well for creating APIs. If you still want to use the routes you are suggesting (which a not RESTful) then Feathers is not the right tool for the job.

One strategy you may want to consider is using a request parameter in a POST body such as { "action": "type" } and use a switch statement to conditionally perform the desired action. An example of this strategy is discussed in this tutorial.

Related

RESTful URL for "Activate"

I have a resource (project) which can be activated and deactivated.
What's the most RESTful URL endpoint for this purpose?
Right now I'm thinking about /projects/:id/activate and /projects/:id/deactivate, but I don't think that's very RESTful.
In addition, I'm not certain what HTTP method to use.
Can you provide some pointers?
Thanks!
The most conventional way to do this is via POST to /projects/:id, with parameters indicating whether you want to activate or deactivate or something else (always leave room for something else).
note that RESTful URLs should refer to things (like projects), not actions. Then the common methods have clear meanings:
PUT: create or replace the thing
PATCH: set properties of the thing
POST: perform an operation on the
thing
GET: retrieve the thing
DELETE: delete the thing
Your can send your requests just to projects/{id} and use PATCH (as you're updating existing object) verb, e.g.
PATCH /projects/123
[
{ "op": "activate|deactivate", ... }
]
Read more: REST API - PUT vs PATCH with real life examples
I know I am a bit late but maybe this might be useful for others.
You can create a noun from your operation and use it as sub-resource: activate -> activation
Now you can use POST and DELETE on this sub-resource.
For example:
POST /projects/:id/activation <-- activate project
DELETE /projects/:id/activation <-- deleting the activation = deactivate
This pattern can work quite well for operations that toggle between on/off state of something.

Which resource should I use to keep my API RESTFul?

I'm building an API to allow the client of the API to send notifications to remind a user to update an Order status. So far, there are two notifications:
when the user hasn't marked the order as received;
when the user hasn't marked the order as done.
I want to build this API to make it simple to extend to other notifications related to the order, but keep a simple URI for the clients of this API.
How can I define my resources in order to keep my API RESTFul?
I was thinking about having one of these structures:
Option 1:
POST: /api/ordernotification/receive/{id}
POST: /api/ordernotification/complete/{id}
Option 2 (omit the status from the resource and post it instead):
POST: /api/ordernotification/?id={id}&statusID={statusID}
EDIT
Option 2.1 (keeping an articulated URI, as suggested by #Jazimov):
POST: /api/ordernotification/{statusID}/{id}.
Which option is more appropriate? Is there any advantage that one option has over the other? Or are there any other option I haven't thought of?
I would go with something along these lines
POST /api/order/1234/notifications/not-received
POST /api/order/1234/notifications/not-completed
Which can later be accessed via
GET /api/order/1234/notifications/not-received
GET /api/order/1234/notifications/not-completed
Or
GET /api/order/1234/notification/8899
There's no real limitation on how semantically rich a URI can be, so you might as well take advantage of that and be explicit.
If I understand you correctly, you have two types of ordernotifications: those for notifying receive and those for notifying complete. If those are two separate data models then I think nesting them is a good idea (i.e. a table called ReceiveOrderNotification and CompleteOrderNotification). If that's the case then you may want to expose two different endpoints entirely, such as POST /api/receiveordernotification and POST /api/completeordernotification.
But I don't think that's the best you can do, given so many overlapping similarities there probably are between order notifications. Now, option 2 is more like a GET, since you're using query parameters, so with your first option let's collapse them into this:
POST: /api/ordernotification/
and then pass it some JSON data to create the notifications
{
"orderId": "orderId",
"userId": "userId",
"prompt": "not marked received/not marked done"
}
I also removed the /{id} because when you POST you create a brand new thing and the id has not been created yet, usually. Even if the client is creating an id and sending it to the API it is a good practice to leave it open so your API can handle creating a new, unique resource in its own way.
This is RESTful is because a POST creates a resource ordernotification with certain data points. Your first option made actions a resource in themselves but that's probably not represented in any data model in your backend. To be as RESTful as possible, your API endpoints should represent the database domains (tables, collections, etc). Then you let your controllers choose what service methods to use given the data sent in the request. Otherwise REST endpoints expose all the logic up front and get to be a long list of unmaintainable endpoints.
I think, to update status of already inserted records, your endpoint should be PUT instead of POST.
You can use
PUT: /api/ordernotification/:id/status/
with clients json data
{
"status": "your_status"
}
according to request data, endpoint should update the record.

Is it REST if I pass the following URI /apps/{id}?control=start

I'm in the process of designing a REST API for our web app.
POST > /apps > Creates an app
PUT > /apps/{id} > Updates the app
I want to start the apps.
Is this REST and if not, how can I make it more RESTful?
POST > /apps/{id}?control=start
Sun Cloud API does this: http://kenai.com/projects/suncloudapis/pages/CloudAPISpecificationResourceModels
Or is it better to:
2. PUT /apps/{id} and include a status parameter in the response Json/XML?
3. POST /apps/{id} and include a status parameter in the response Json/xml?
4. POST /apps/start?app={id}
I think the right question here is more whether the HTTP verbs are being used as intended rather than whether the application is or is not as RESTful as possible. However, these days the two concepts are pretty much the same.
The thing about PUT is that whatever you PUT you should be able to immediately GET. In other words, PUT does a wholesale replacement of the resource. If the resource stored at apps/5 is something that has a "control" attribute as part of its state, then the control=start part should be part of the representation you put. If you want to send just the new piece of the resource, you are doing a PATCH, not a PUT.
PATCH is not widely supported, so IMHO you should use a POST. POST has no requirements of safety or idempotency; generally you can do whatever you want with a POST (more or less), including patching parts of a resource. After all that is what you do when you create a new item in a collection with a POST. Updating a portion of a resource is not really much different.
Generally though you POST new data in the request body, not as query parameters. Query parameters are used mostly for GETs, because you are, well, querying. :)
Does starting an app changes it state? (to "running", for example) If it does what you're actually doing is updating the state of the resource (application). That seems like a good use for the PUT operation. Although as Ray said, if control is part of the state of the resource, the body of the PUT request should contain the state you're updating. I believe a partial update would be possible (CouchDB uses this).
On the other hand, if starting an app means creating a new resource (representing the app execution, for example), the POST method would be a great fit. You could have something like this:
POST /app/1/start
Which would result in a HTTP/1.1 201 Created. Then, to access the information on the created execution, you could use a URL like this:
GET /app/1/execution/1
To me, this would seem like a good "Restful" approach. For more information, check out this article.
PUT apps/{id}
I would PUT the app to update it's status from off to on
I like to do something like,
POST /runningapps?url=/app/1

Confused about Http verbs

I get confused when and why should you use specific verbs in REST?
I know basic things like:
Get -> for retrieval
Post -> adding new entity
PUT -> updating
Delete -> for deleting
These attributes are to be used as per the operation I wrote above but I don't understand why?
What will happen if inside Get method in REST I add a new entity or inside POST I update an entity? or may be inside DELETE I add an entity. I know this may be a noob question but I need to understand it. It sounds very confusing to me.
#archil has an excellent explanation of the pitfalls of misusing the verbs, but I would point out that the rules are not quite as rigid as what you've described (at least as far as the protocol is concerned).
GET MUST be safe. That means that a GET request must not change the server state in any substantial way. (The server could do some extra work like logging the request, but will not update any data.)
PUT and DELETE MUST be idempotent. That means that multiple calls to the same URI will have the same effect as one call. So for example, if you want to change a person's name from "Jon" to "Jack" and you do it with a PUT request, that's OK because you could do it one time or 100 times and the person's name would still have been updated to "Jack".
POST makes no guarantees about safety or idempotency. That means you can technically do whatever you want with a POST request. However, you will lose any advantage that clients can take of those assumptions. For example, you could use POST to do a search, which is semantically more of a GET request. There won't be any problems, but browsers (or proxies or other agents) would never cache the results of that search because it can't assume that nothing changed as a result of the request. Further, web crawlers would never perform a POST request because it could not assume the operation was safe.
The entire HTML version of the world wide web gets along pretty well without PUT or DELETE and it's perfectly fine to do deletes or updates with POST, but if you can support PUT and DELETE for updates and deletes (and other idempotent operations) it's just a little better because agents can assume that the operation is idempotent.
See the official W3C documentation for the real nitty gritty on safety and idempotency.
Protocol is protocol. It is meant to define every rule related to it. Http is protocol too. All of above rules (including http verb rules) are defined by http protocol, and the usage is defined by http protocol. If you do not follow these rules, only you will understand what happens inside your service. It will not follow rules of the protocol and will be confusing for other users. There was an example, one time, about famous photo site (does not matter which) that did delete pictures with GET request. Once the user of that site installed the google desktop search program, that archieves the pages locally. As that program knew that GET operations are only used to get data, and should not affect anything, it made GET requests to every available url (including those GET-delete urls). As the user was logged in and the cookie was in browser, there were no authorization problems. And the result - all of the user photos were deleted on server, because of incorrect usage of http protocol and GET verb. That's why you should always follow the rules of protocol you are using. Although technically possible, it is not right to override defined rules.
Using GET to delete a resource would be like having a function named and documented to add something to an array that deletes something from the array under the hood. REST has only a few well defined methods (the HTTP verbs). Users of your service will expect that your service stick to these definition otherwise it's not a RESTful web service.
If you do so, you cannot claim that your interface is RESTful. The REST principle mandates that the specified verbs perform the actions that you have mentioned. If they don't, then it can't be called a RESTful interface.

Need guidance in creating Rails 3 Engine/Plugin/Gem

I need some help figuring out the best way to proceed with creating a Rails 3 engine(or plugin, and/or gem).
Apologies for the length of this question...here's part 1:
My company uses an email service provider to send all of our outbound customer emails. They have created a SOAP web service and I have incorporated it into a sample Rails 3 app. The goal of creating an app first was so that I could then take that code and turn it into a gem.
Here's some of the background: The SOAP service has 23 actions in all and, in creating my sample app, I grouped similar actions together. Some of these actions involve uploading/downloading mailing lists and HTML content via the SOAP WS and, as a result, there is a MySQL database with a few tables to store HTML content and lists as a sort of "staging area".
All in all, I have 5 models to contain the SOAP actions (they do not inherit from ActiveRecord::Base) and 3 models that interact with the MySQL database.
I also have a corresponding controller for each model and a view for each SOAP action that I used to help me test the actions as I implemented them.
So...I'm not sure where to go from here. My code needs a lot of DRY-ing up. For example, the WS requires that the user authentication info be sent in the envelope body of each request. So, that means each method in the model has the same auth info hard coded into it which is extremely repetitive; obviously I'd like for that to be cleaner. I also look back now through the code and see that the requests themselves are repetitive and could probably be consolidated.
All of that I think I can figure out on my own, but here is something that seems obvious but I can't figure out. How can I create methods that can be used in all of my models (thinking specifically of the user auth part of the equation).
Here's part 2:
My intention from the beginning has been to extract my code and package it into a gem incase any of my ESP's other clients could use it (plus I'll be using it in several different apps). However, I'd like for it to be very configurable. There should be a default minimal configuration (i.e. just models that wrap the SOAP actions) created just by adding the gem to a Gemfile. However, I'd also like for there to be some tools available (like generators or Rake tasks) to get a user started. What I have in mind is options to create migration files, models, controllers, or views (or the whole nine yards if they want).
So, here's where I'm stuck on knowing whether I should pursue the plugin or engine route. I read Jordan West's series on creating an engine and I really like the thought of that, but I'm not sure if that is the right route for me.
So if you've read this far and I haven't confused the hell out of you, I could use some guidance :)
Thanks
Let's answer your question in parts.
Part One
Ruby's flexibility means you can share code across all of your models extremely easily. Are they extending any sort of class? If they are, simply add the methods to the parent object like so:
class SOAPModel
def request(action, params)
# Request code goes in here
end
end
Then it's simply a case of calling request in your respective models. Alternatively, you could access this method statically with SOAPModel.request. It's really up to you. Otherwise, if (for some bizarre reason) you can't touch a parent object, you could define the methods dynamically:
[User, Post, Message, Comment, File].each do |model|
model.send :define_method, :request, proc { |action, params|
# Request code goes in here
}
end
It's Ruby, so there are tons of ways of doing it.
Part Two
Gems are more than flexible to handle your problem; both Rails and Rake are pretty smart and will look inside your gem (as long as it's in your environment file and Gemfile). Create a generators directory and a /name/name_generator.rb where name is the name of your generator. The just run rails g name and you're there. Same goes for Rake (tasks).
I hope that helps!