Skip to main content
Post Undeleted by Ray
Post Deleted by Ray
added 565 characters in body
Source Link
Ray
  • 49
  • 1
  • 5
  • Data efficient
  • Big amount of layers, lasagna code
  • Flexible for data efficient multi-usage.
  • Not data efficient
  • Small amount of layers
  • Not flexible for data efficient multi-usage.
  • Data efficient
  • Small amount of layers
  • Flexible for data efficient multi-usage.
  • Data efficient
  • Big amount of layers, lasagna code
  • Flexible
  • Not data efficient
  • Small amount of layers
  • Not flexible
  • Data efficient
  • Small amount of layers
  • Flexible
  • Big amount of layers, lasagna code
  • Flexible for data efficient multi-usage.
  • Small amount of layers
  • Not flexible for data efficient multi-usage.
  • Small amount of layers
  • Flexible for data efficient multi-usage.
added 565 characters in body
Source Link
Ray
  • 49
  • 1
  • 5

Example: Lets say we need to get all the users who commented on all posts of a single thread with its posts comments users.

getCommentUsersOnAllPostsFromThreadgetThreadWithPostCommentUsers(threadUuid) {
    const usersthread = [];new Thread();

    // by default flat, however becomes lasagna code.
    // data conscious, layer heavy, flexible.
    this.http.request('threads/' + threadUuid).then((threadData) => {
        Object.assign(thread, threadData);

        this.http.request('threads/' + threadUuid + '/posts').then((posts) => {
            thread.posts = posts;

            posts.forEach(post => {
                this.http.request('posts/' + post.uuid + '/comments').then((comments) => {
                    post.comments = comments;

                    comments.forEach(comment => {
                        this.http.request('users/' + comment.user_uuid).then((user) => {
                        users    comment.pushuser = user
                            console.log(comment.user);
                        });
                    });
                });
            });
        });
    });
}
getCommentUsersOnAllPostsFromThreadgetThreadWithPostCommentUsers(threadUuid) {
    const usersthread = [];new Thread();

    // by default has nested objects, very simple but inefficient
    // not data conscious, not layer heavy, not flexible
    this.http.request('threads/' + threadUuid).then((threadthreadData) => {
        Object.assign(thread, threadData);

        thread.posts.forEach(post => {
            post.comments.forEach(comment => {
                usersconsole.pushlog(comment.user);
            });
        });
    });
}
getCommentUsersOnAllPostsFromThreadgetThreadWithPostCommentUsers(threadUuid) {
    const usersthread = [];new Thread();

    // by default flat, adds nests depending on resources parameter
    // flexible, data conscious, not layer heavy
    this.http.request('threads/' + threadUuid + '?resources=posts.comments.user').then((threadthreadData) => {
        Object.assign(thread, threadData);

        thread.posts.forEach(post => {
            post.comments.forEach(comment => {
                usersconsole.pushlog(comment.user);
            });
        });
    });
}

My requests would be flat by default, however my requests have the ability to call on a demand basis for certain nested relationshipsresources without creating a bunch of custom routes and being data efficient.

Example: Lets say we need to get all the users who commented on all posts of a single thread.

getCommentUsersOnAllPostsFromThread(threadUuid) {
    const users = [];

    // by default flat, however becomes lasagna code.
    this.http.request('threads/' + threadUuid + '/posts').then((posts) => {
        posts.forEach(post => {
            this.http.request('posts/' + post.uuid + '/comments').then((comments) => {
                comments.forEach(comment => {
                    this.http.request('users/' + comment.user_uuid).then((user) => {
                        users.push(user);
                    });
                });
            });
        });
    });
}
getCommentUsersOnAllPostsFromThread(threadUuid) {
    const users = [];

    // by default has nested objects, very simple but inefficient
    this.http.request('threads/' + threadUuid).then((thread) => {
        thread.posts.forEach(post => {
            post.comments.forEach(comment => {
                users.push(comment.user);
            });
        });
    });
}
getCommentUsersOnAllPostsFromThread(threadUuid) {
    const users = [];

    // by default flat, adds nests depending on resources parameter
    this.http.request('threads/' + threadUuid + '?resources=posts.comments.user').then((thread) => {
        thread.posts.forEach(post => {
            post.comments.forEach(comment => {
                users.push(comment.user);
            });
        });
    });
}

My requests would be flat by default, however my requests have the ability to call on a demand basis for certain nested relationships without creating a bunch of custom routes and being data efficient.

Example: Lets say we need to get a thread with its posts comments users.

getThreadWithPostCommentUsers(threadUuid) {
    const thread = new Thread();

    // by default flat, however becomes lasagna code.
    // data conscious, layer heavy, flexible.
    this.http.request('threads/' + threadUuid).then((threadData) => {
        Object.assign(thread, threadData);

        this.http.request('threads/' + threadUuid + '/posts').then((posts) => {
            thread.posts = posts;

            posts.forEach(post => {
                this.http.request('posts/' + post.uuid + '/comments').then((comments) => {
                    post.comments = comments;

                    comments.forEach(comment => {
                        this.http.request('users/' + comment.user_uuid).then((user) => {
                            comment.user = user
                            console.log(comment.user);
                        });
                    });
                });
            });
        });
    });
}
getThreadWithPostCommentUsers(threadUuid) {
    const thread = new Thread();

    // by default has nested objects, very simple but inefficient
    // not data conscious, not layer heavy, not flexible
    this.http.request('threads/' + threadUuid).then((threadData) => {
        Object.assign(thread, threadData);

        thread.posts.forEach(post => {
            post.comments.forEach(comment => {
                console.log(comment.user);
            });
        });
    });
}
getThreadWithPostCommentUsers(threadUuid) {
    const thread = new Thread();

    // by default flat, adds nests depending on resources parameter
    // flexible, data conscious, not layer heavy
    this.http.request('threads/' + threadUuid + '?resources=posts.comments.user').then((threadData) => {
        Object.assign(thread, threadData);

        thread.posts.forEach(post => {
            post.comments.forEach(comment => {
                console.log(comment.user);
            });
        });
    });
}

My requests would be flat by default, however my requests have the ability to call on a demand basis for certain nested resources without creating a bunch of custom routes and being data efficient.

Source Link
Ray
  • 49
  • 1
  • 5

RESTful API - Adding nested resources as a query parameter?

I recently had thoughts on handling the flat vs nested architecture when designing a RESTful API.

Would there be anything wrong with having a system where your nested resources can be specified within a query parameter of the API request? This is only needed in certain complex situations, otherwise you would just access it regularly through collections/instance/collections/instance.

Example: Lets say we need to get all the users who commented on all posts of a single thread.

Flat architecture way:

getCommentUsersOnAllPostsFromThread(threadUuid) {
    const users = [];

    // by default flat, however becomes lasagna code.
    this.http.request('threads/' + threadUuid + '/posts').then((posts) => {
        posts.forEach(post => {
            this.http.request('posts/' + post.uuid + '/comments').then((comments) => {
                comments.forEach(comment => {
                    this.http.request('users/' + comment.user_uuid).then((user) => {
                        users.push(user);
                    });
                });
            });
        });
    });
}
  • Data efficient
  • Big amount of layers, lasagna code
  • Flexible

This feels the most encapsulated and straight forward. However it starts to become a bit redundant and unfavorable when you deal with alot of relationships.

Nested architecture way:

getCommentUsersOnAllPostsFromThread(threadUuid) {
    const users = [];

    // by default has nested objects, very simple but inefficient
    this.http.request('threads/' + threadUuid).then((thread) => {
        thread.posts.forEach(post => {
            post.comments.forEach(comment => {
                users.push(comment.user);
            });
        });
    });
}
  • Not data efficient
  • Small amount of layers
  • Not flexible

The nested way is nice from a convenience perspective but isn't very flexible if you care about minimizing data.

So my idea was to combine the two, where I can reap the benefits of a simple flat architecture, but also have the benefits of loading nests in one request.

Flat and nested hybrid way:

getCommentUsersOnAllPostsFromThread(threadUuid) {
    const users = [];

    // by default flat, adds nests depending on resources parameter
    this.http.request('threads/' + threadUuid + '?resources=posts.comments.user').then((thread) => {
        thread.posts.forEach(post => {
            post.comments.forEach(comment => {
                users.push(comment.user);
            });
        });
    });
}
  • Data efficient
  • Small amount of layers
  • Flexible

My requests would be flat by default, however my requests have the ability to call on a demand basis for certain nested relationships without creating a bunch of custom routes and being data efficient.

Authorization would still be done on the serverside, allowing only certain resources depending on request.

Would this be a bad practice/design choice? What are your thoughts? Is there something out there for this and I am reinventing the wheel?

Thanks