What are the benefits of routers in dynamic URI analysis?

I'm trying to make an architectural decision, and I'm worried that I'm missing something big with regards to URL routing / mapping when it comes to developing a basic REST API.

Creating routing classes, and those that are commonly found within the framework of the REST API, for which you need to manually map the URL for the class and the class method (action), sort of like an inability to encapsulate the problem. When all this can be determined by analyzing the URL dynamically and having an automatic router or front page controller.

GET https://api.example.com/companies/

A collection resource that gets a list of all companies.

GET https://api.example.com/companies/1

Selects an individual company by identifier.

What looks like a template: https://api.example.com/<controller>/<parameter>/

Advantage 1: URL decoupling and abstraction

I assume one of the advantages of working with a regular routing class is that you can separate or drop the URL from the resource / physical class. This way, you can have an arbitrary URL, for example GET https://api.example.com/poo/ instead of GET https://api.example.com/companies/ , which all companies will choose if you like it .

But in almost every example and use case that I saw, the desire to have a URL that matches the required controller , action and parameters, 1: 1.

Another possible advantage is that collecting resources in a resource or nested resources can be more easily achieved by matching URLs and typical routers. For instance:

GET https://api.example.com/companies/1/users/

OR

GET https://api.example.com/companies/1/users/1/

It may be difficult to come up with a paradigm that can dynamically analyze this in order to know which controller you need to call to get data, which parameters to use and where to use them. But I think I came up with a standard way that could make this work dynamically.

While manually matching it would be easy.

I could just redirect the GET https://api.example.com/companies/1/users/ to the user controller, and not to the company controller, bypassing it, and simply set the parameter “1” as the company identifier for the WHERE clause.

Allowance 1.1: No binding to physical paths

An additional advantage of 1 is that the developer can completely change the structure of URLs and the structure of folders without affecting the API, because everything is displayed in an abstract way. If I want to move files, folders, classes or rename them, you just need to change the display / routing.

But still you can’t get this advantage, because even if you had to move the whole API to another place, there is a trivial change in .htaccess with the correction of this point.

So this is:

GET https://api.example.com/companies/

TO

GET https://api.example.com/v1/companies/

Would not affect the code, even in the least. Even with a dynamic router.

Advantage 2: control over what works with functionality

Another advantage I believe that a typical router class gives you, through a dynamic router that simply interprets and parses the URL, is control over what functionality you want the API to provide to the consumer. If you just do everything dynamically, you drop your pants, automatically providing your consumer access to the entire system.

I see this as a possible advantage for a dynamic router, since then you do not have to manually identify and map all routes to resources. All this is there, automatically. To solve the impact problem, I would probably do the opposite by specifying a blacklist of what functionality the API user shouldn't use. I could be more time-efficient by defining a blacklist and then defining each useful resource using matching. On the other hand, it is also dangerous. You can even make a whitelist ... which looks like a typical router, but you don't need any advanced logic at all. This is just a list of URLs that the system would check before passing the URL to a dynamic router. Or it may just be a private property of the dynamic router class.

Advantage 3: When HTTP Methods Fail to Bill

In one case, when I see typical routers, you must perform an action that conflicts with an existing resource. Let me explain.

Suppose you want to authenticate a user by running the login function in your user class. But now you cannot POST https://api.example.com/users/ with credentials, because it is reserved for adding a new user. Instead, you need to somehow start the method of entering your custom class. You also do not want to use POST https://api.example.com/users/login/ , because then you use verbs other than HTTP methods. However, with a typical router, you can simply map this directly, as mentioned earlier. Easy.

url => "https://api.example.com/tenant/"
Controller => "users"
Action => "login"
Params => "api_key, api_secret"

But, again, I see a plausible alternative. I could just create another controller, called a login or tenant, which launches my user controller and launches the login function. Thus, the consumer could just POST https://api.example.com/tenant/ , with credentials and benefits. Authentication

Although in order to get this alternative to work, I would have to physically create another controller when I wouldn’t use the URL map. But this separation of problems, functionality and resources is also not bad. But perhaps the main compromise, would you rather just define a URL route or do you need to create new classes for every nuance you come across?

What I do not see or do not understand? I missed the basic concept here and just don’t know? Are there more advantages to having typical URL mapping and routing classes and functionality that I just don’t know about, or did I succeed?

+6
source share
1 answer

Many of the routing benefits that you describe are correct, and some of what you say about physical mappings is also true. I would like to add some experience / practical information that has colored my opinion on routers over the past few years.

  • First of all, dynamic URL analysis works well (most of the time) when archiving an application according to the MVC design pattern. For example, I once created a very large application using Kohana, which is a hierarchical MVC structure that allows you to extend controllers and models to create nested URLs. In general, this makes a lot of sense. But there were many times when it simply did not make sense to put together a whole system of classes and models around the need for one-time URLs to make the application more functional. But there are also times when MVC is not the design pattern that you use, and therefore this is not the defining function of your API, and the routing in this scenario is beautiful. It is easy to see this problem at work, playing with frameworks that have great structural freedom, such as Slim framework or Express.js.

  • more often than people think, a fully functional API will have an RPC function element for it in addition to the main RESTful endpoints available for consumption. And not only these additional functions make more sense as a consumer when they adorn existing resource method comparisons. This usually happens after you have created most of your application and covered most of your databases, and then you realize that there are several small functions that you would like to add in relation to a resource that does not fit purely into categories CREATE / READ / UPDATE / DELETE. you will know it when you see it.

  • it really cannot be understated, it is much safer not to hack into the actual structure of controllers and models, add, delete, change things for the sole purpose of adding an endpoint that is not essentially following the same rules of other controller methods (API endpoints).

  • one more important thing: API endpoints are actually more scalable than we often understand. I mean, you can be fine with the structure of your endpoints on Monday, and then on Friday you will get this task from top to bottom, saying that you need to change all these API calls to a different structure, and thats fine. but if you have a large application, it requires a very, very significant amount of file renaming, class renaming, bindings and all kinds of very legible codes, when the framework you use has strict rules for class naming, file naming, the physical structure of the file path and the like ... just imagine changing the name of the class so that it works with the new structure, and now you need to look for all the lines of code that created the instance of the old class and change it. In addition, in this case, we can say that the problem is that your code is closely related to the structure of the URL of your API, and it is not very convenient to service if your URL needs to be changed.

In any case, you really need to decide what works best for a particular application. but the more you use routers, the more you will see why they are so useful.

+1
source

Source: https://habr.com/ru/post/955430/


All Articles