1

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?

Ivan
  • 34,531
  • 8
  • 55
  • 100

3 Answers3

1

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})

gui3
  • 1,711
  • 14
  • 30
  • Thank you for taking the time to answer. It's quite a new way for me to organize the API and there definitely a lot to think about. The thing that bothered me at first was the constraints set by FeathersJS both on the routes and on the available request methods. – Ivan Jul 29 '20 at 07:46
0

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.

Daff
  • 43,734
  • 9
  • 106
  • 120
  • Thank you for your answer. I didn't find this FAQ page while reading through the docs. It's very enlightening to see an API being built this way. After watching the video, I have a question that seems related: at [19:20](https://youtu.be/IOwilPI4LFg?list=PLwSdIiqnDlf_lb5y1liQK2OW5daXYgKOe&t=1156) you show two client-side methods calling `submissionService#patch` with two different parameters, what do you mean by "you would do this with hooks on the server"?. – Ivan Jul 29 '20 at 08:04
0

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.