Home > OS >  REST - User and User Profile (1:1 relation) routes and endpoints structure
REST - User and User Profile (1:1 relation) routes and endpoints structure

Time:09-30

I am currently developing a REST api (using mongoDb, node.js and express) that will handle 4 kinds of users. I have decided to use a collection that stores common data between all types of users (email, hash, role, etc.) and 4 collections storing profile data for the respective type of user. Between the the user profile and the user will be a 1 to 1 relation. Also, keep in mind that the users will be referenced in other collections (mainly for the user profile data). I am wondering what is the best way to structure my routes and endpoints. Should I have a separate route for every user type (let's say /students, /proffessors and so on) or just one endpoint (/users) that will handle all the user related requests. For example, if I want to do user profile related requests (GET, PATCH, etc.), should I use /users/{userId}/profile or /students/{studentId}. For requests like /users/{userId}/profile/proffessors I am guessing that the second option (/students/{studentId}/professors)is better to avoid extra long URIs (since the userId can get pretty long).

One last question related to this data model: like I said, I will be referencing users in other collections for the user profile data. Should I reference the user or just the user profile, to avoid joining 3 collections?

Please bear in mind that I am quite new to web dev and trying to learn. Thanks a lot :)

CodePudding user response:

Both are ok, REST does not concern about path structure. The URI standard writes only that path should contain the hierarchical part of the URI and query should contain the non-hierarchical part.

As of the resources, they should not come from database structure. You need to think about the operations you want to support and translate operation name into HTTP method and web resource. Something like readUserProfile(userId) into GET /users/{userId}/profile. Normally with REST you send hyperlinks to the webservice consumer something like

{
    metadata: {
        operation: {
            name: "readUserProfile",
            parameters: ["userId"]
        },
        httpMethod: "GET", 
        uriTemplate: "/users/{userId}/profile",
        parameters: {
            userId: {
                type: "UserId",
                required: true
            }
        }
    },
    data: {
        type: "readUserProfile",
        parameters: {
            userId: 123
        }
    }
}

Your can separate the metadata into a documentation JSON file and send only the data:

{
    type: "readUserProfile",
    parameters: {
        userId: 123
    }
}

And the service consumer code can do

service = new REST.WebService("https://example.com/api/docs.json");
profileData = await service.readUserProfile(123);

or

service = new REST.WebService("https://example.com/api/docs.json");
userData = await service.findUser({userId: 123});
link = response.findLink({type: service.readUserProfile});
profileData = await link.follow();

This is why the consumer should not care much about the URI structure as long as the URI and URI template standards and REST constraints are followed. The length does not matter at all unless you violate the HATEOAS constraint. But even in that case your documentation must contain the URI templates, so it is just copy-paste for the service consumer developers. You can even support both URI structures if you want to, though it makes extra work for the REST webservice developers to support both.

As of my opinion I prefer the flat structure, because it makes the URI simpler, something like /students/{userId} instead of /users/{userId}/student, but if the API is big, then routing gets harder and slower this way I think. There is no big difference though. Another thing you need to keep in mind that in some cases the same person can be student and professor too, for example I know such people. It is a business and security decision whether you allow this kind of mixed accounts or you give them 2 separate accounts. I prefer the latter from security perspective or at least choosing the role for the session.

  • Related