Clear url vs Queried strings - web service request from my iOS client

I have searched a lot for a clear answer or explanation, but I cannot find an exhaustive one.

I am creating a mobile application that is mainly based on my backend data. I can structure most of my queries on my server (based on php) using pure soothing query or query with query strings.

2 questions:

1. Say I have a class of friends. I want to get or establish Dani's friends.

At rest I would do:

http://www.example.com/Dani/friends - GET (to get all his friends) http://www.example.com/Dani/friends - POST (to create a new friend for Dani) 

Using requested strings:

 Http://www.example.com/ user=Dani & action=get_friends (GET method I assume?) http://www.example.com/ user=Dani & action=add_friend (POST method I assume?) 

So, for the first example, we have caching in place, plus one permanent, very readable URL.

In the second case, we really don’t have a cache (even if you have, for some reason you need to tell the proxy server to update the friends list cache after one call to the second URL to add a friend), since these are two different URIs. At rest, this is done automatically by the definition of http methods (post / put makes the resource "dirty")

I'm here?

I want to know what is the best option: Caching, security, a single entry point (in php code), simper for implementation (for both client and server) and so ...

2. How to create a URL to find only photos of some friends? (let's say those that are in a particular place.)

I thought:

 http://www.example.com/Dani/friends?long=1&lat=2&field=photos 

Is this right, or is there a better way?

+4
source share
2 answers

URL Design
One of the most important things to remember about building a REST URL is that each URL must identify one resource. In general, this means that URLs are usually broken into parts:

  • Lists of top-level objects: /users and /photos
  • Top Level Instance Instance: /users/1/Dani and /photos/4356
  • Instance level lists:
    • /users/1/Dani/friends - Dani's Friends
    • /users/1/Dani/photos - Dani's Photos

Resource Interaction
Interactions with these resources (i.e., Create, read, update, delete) are handled through "HTTP verbs" or " HTTP methods ", which each URL is actually called. The advantage of this is that each resource (or “thing”) you only need to know how to do 4 different things, which means that you have a much simpler application.

Your application is also much more structured and divided, which simplifies testing and allows you to update and make changes to it much easier, because things are more loosely coupled.

Once you don't have a clear 1-1 connection between a single resource and a single URL, you no longer have RESTful URLs. After you start inserting action strings into the query string, you are essentially making remote procedure calls (RPC), not REST. Everything passing through a central point brings things together more than they should be, making your architecture tough, hard to change, and very difficult to test.

Search
The trick is that for any type of resource such as a list, you can have this list as a result of some query. It says nothing that the list should always be the same. It would be inappropriate to use http://www.example.com/Dani/friends?long=1&lat=2&field=photos , because this will return to you a list of photos of Dani's friends who are quite far from Dani User.

Since you are looking for photos, and we already have a URL that identifies the “Photos List” resource, that is, a URL that we must use, but just to get these photos with certain attributes.

So, for your example search of all photos belonging to a specific user (which may be one of Dani's friends, you can do something like:

 GET /photos?owner=[userId] 

and you can only search for photographs taken within 1 km of some lat / long coordinate:

 GET /photos?owner=[userId]&radius=1&lat=[someLat]&long=[someLong] 

Or, if you look a little wider, maybe you need photos of all Dani's friends from this area:

 GET /photos?ownerFriendOf=[Dani userId]&radius=1&lat=[someLat]&long=[someLong] 

In all of these cases, you are viewing the list of photos based on the query string that you send to the list of photos in /photos .

Caching
Caching is just an added bonus. Theoretically, any request can be cached, but you do not need to worry about it right now. In general, however, if you stick to the REST architecture, you'll be fine when the time comes.

Security
HTTP has a number of built-in ways to solve the security problem, and any of them will work, depending on how secure your application is. Security Basic and Digest are well suited for connecting applications with applications, as they send their authentication tokens (i.e. username and password) along with the request. However, for the security flow that is associated with the user, you most likely want to use the session mechanism and use the HTTP Cookie headers to track the session.

In all cases, however, at any time when the username / password is moved from the client to the server, it must be associated with a secure SSL connection (https) so that attackers do not sniff it. For particularly sensitive applications, all interaction can be through an SSL connection, and for other applications there can only be an login sequence. In general, however, being safer is better than less.

Ease of implementation
On the security front, most web frameworks have built-in methods that can handle all the security methods I have described. You might be wondering if you need to use a web framework, and although this is not a strictly required requirement, it will significantly reduce the amount of work that you have to do, and at the same time it will reduce the number of errors, as most of the “heavy lifting” processed by the frame and has been very well tested.

Many frameworks today have built-in support for RESTful request processing, and you can get up and running quickly. RPC-based support is often less supported because it does not have a well-defined application architecture such as REST, but it is still possible in almost any environment.

In the long run, however, you are likely to get a much better chance for your dollar by going with RESTful architecture.

+12
source

Before addressing your specific issues, it should be noted that the idea that having “clean” / restricted URIs means that your application is more RESTful is a fallacy. A query string URI can be just as good. Having said that, URIs can usually have read flags that you are doing something wrong RESTful. In your case, this mention of action=method in your URI is a flag. The action to be taken must be completely derived from the HTTP method (more generally, your "unified interface method").

The most important argument for option 1 may be that creating a GET request for a URI should always be safe. When you start using methods like add_friend or, even worse, delete_friend in a URI accessible through a GET request, you run the risk of accidentally getting into one of these URIs and performing an unwanted, unsafe operation. Separate HTTP methods exist to prevent such errors.

To your questions:

  • Caching Most modern clients / browsers and proxies should be able to cache resources using query strings in the URI (provided that the order of the query string does not change), but you are correct, the old URLs will be more secure in terms of caching.

    Single entry point . You can still have one entry point with "calmer" URLs. Just need to use something like mod_rewrite (assuming you are using Apache) to direct all urls to a single php controller file. Other HTTP servers, such as nginx, have built-in built-in support. If you use Apache and do not have mod_rewrite , you can take advantage of the fact that the request to /api.php/Dani/friends will still go to the php file api.php .

    Implementation : client-side implementation is an equal effort. Server-side implementation really depends on how the internal structure of your application is structured. Do you use ORM? Are friends a user relationship? If so, it should just be able to map the URIs, e.g. /Dani/friends , to (pseudocode). 1. Initialize the user "Dani". 2. Relationships Dani Dani. 3. Presentation echo out.

    If your base code is already heavily controlled by the instance method (e.g. get_friends ), it will work a little ahead, but it may be worth it. When you open direct methods in a URI, you have now linked your URI to the underlying source code, which makes maintenance / updating difficult and error prone. There are also potential security risks if you are not careful when placing such methods in a URI.

    It is worth noting that the first psuedocode recommendation may also suffer from similar problems on a less severe scale. Sometimes it's best to create unique descriptors for URIs (like Sinatra , Express , or similar PHP clones . This is your safest option when it comes to flexibility, security, maintenance, and “future validation”.

  • http://www.example.com/Dani/friends?long=1&lat=2&field=photos is a perfectly acceptable URI (see introductory notes). It is no more or less calm than a URI with a bunch of '/, and it does not have any red flags (e.g. verbs in a URI).

+4
source

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


All Articles