简体   繁体   中英

Where to put current user context data in response JSON?

Consider a social network. It has posts. For feed, you request /feed and get the list of posts.

In the UI, there are things to show for a post, like if the user liked the post or not, if the user starred it or not, etc. These things don't look like they belong inside the post object.

Another case is when you fetch the likes. The frontend needs to know if the user in each 'like' object is being followed or not.

Where to put this info in the response JSON?

Its depends on your application and which data you want to show to the user. For ex,consider you are listing a user's feeds. In that feed,you want to show

  1. Message
  2. Liked by the current user or not(i don't know the difference between liked and stared)
  3. Number of likes
  4. List of liked users.
  5. shared by the user or not
  6. Shared count
  7. List ofShared users.

etc..

In the above list,

Some data need two api fetch to get complete info and some not. For example,"List of liked users","List of Shared users". This is generally a dynamic data module. You have to get those details in a separate api for better performance of the server and also data integrity.

In some cases,some apps needs sneak peek of the liked shared users info in the listing page. In that case,you can include the some fixed small number of users details in the same list /feeds response itself and include the "See More(like Facebook)" option in the UI.

Some static singular data(single column data) can be list in the initial get /feeds itself.

I wonder why don't you follow the same twitter's list tweets style,

https://dev.twitter.com/rest/reference/get/search/tweets

{
  "coordinates": null,
  "favorited": false,
  "truncated": false,
  "created_at": "Fri Sep 21 23:40:54 +0000 2012",
  "id_str": "249292149810667520",
  "entities": {
    "urls": [

    ],
    "hashtags": [
      {
        "text": "FreeBandNames",
        "indices": [
          20,
          34
        ]
      }
    ],
    "user_mentions": [

    ]
  },
  "in_reply_to_user_id_str": null,
  "contributors": null,
  "text": "Thee Namaste Nerdz. #FreeBandNames",
  "metadata": {
    "iso_language_code": "pl",
    "result_type": "recent"
  },
  "retweet_count": 0,
  "in_reply_to_status_id_str": null,
  "id": 249292149810667520,
  "geo": null,
  "retweeted": false,
  "in_reply_to_user_id": null,
  "place": null,

  "user": 
  {
    "profile_sidebar_fill_color": "DDFFCC",
    "profile_sidebar_border_color": "BDDCAD",
    "profile_background_tile": true,
    "name": "Chaz Martenstein",
    "profile_image_url": "http://a0.twimg.com/profile_images/447958234/Lichtenstein_normal.jpg",
    "created_at": "Tue Apr 07 19:05:07 +0000 2009",
    "location": "Durham, NC",
    "follow_request_sent": null,
    "profile_link_color": "0084B4",
    "is_translator": false,
    "id_str": "29516238",
    "entities": {
      "url": {
        "urls": [
          {
            "expanded_url": null,
            "url": "http://bullcityrecords.com/wnng/",
            "indices": [
              0,
              32
            ]
          }
        ]
      },
      "description": {
        "urls": [

        ]
      }
    },
    "default_profile": false,
    "contributors_enabled": false,
    "favourites_count": 8,
    "url": "http://bullcityrecords.com/wnng/",
    "profile_image_url_https": "https://si0.twimg.com/profile_images/447958234/Lichtenstein_normal.jpg",
    "utc_offset": -18000,
    "id": 29516238,
    "profile_use_background_image": true,
    "listed_count": 118,
    "profile_text_color": "333333",
    "lang": "en",
    "followers_count": 2052,
    "protected": false,
    "notifications": null,
    "profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/9423277/background_tile.bmp",
    "profile_background_color": "9AE4E8",
    "verified": false,
    "geo_enabled": false,
    "time_zone": "Eastern Time (US & Canada)",
    "description": "You will come to Durham, North Carolina. I will sell you some records then, here in Durham, North Carolina. Fun will happen.",
    "default_profile_image": false,
    "profile_background_image_url": "http://a0.twimg.com/profile_background_images/9423277/background_tile.bmp",
    "statuses_count": 7579,
    "friends_count": 348,
    "following": null,
    "show_all_inline_media": true,
    "screen_name": "bullcityrecords"
  },
  "in_reply_to_screen_name": null,
  "source": "web",
  "in_reply_to_status_id": null
}

You have two options:

  • Make a separate API method for getting information about user context data - /api/users/1/feeds/1 .Pay attention, that this option will force you to send request per feed. So, if you'll have 1000 feeds - you will have 1000 + 1 request (so called N+1 problem).
    As for me - it's not a good idea.

  • You can store user data in json, for example is this way:

     { "feedName": "feed1", ... "currentUser": { "liked": true, "starred": true } } 

    By using this option you will avoid N+1 requests problem in your RESTful service

For all the users, the post resource should be the same. Adding specific user context info inside it seems like polluting it

I can see where you're coming from and I quite agree.

Ivan's 1st solution should not be used as he already mentioned, his 2nd is better but then if you GET the posts JSON which should contain only post objects, there is also this currentUser that doesn't really belong there.

My suggestion is that for each post you keep track of which users have liked and/or starred it, etc. Then you keep a clean structure while still having the info you need available in the same request/response.

Example

GET /feed HTTP/1.1

[
    {
        "text": "hello world, im a post!",
        "author": "Jack",
        "likes": 3,
        "likedBy": [
            "John",
            "James",
            "Jessica"
        ],
        "stars": 2,
        "starredBy": [
            "John",
            "Mary"
        ]
    },
    {
        "text": "hello world, im also a post! :D",
        "author": "Mary",
        "likes": 1,
        "likedBy": [
            "James"
        ],
        "stars": 0,
        "starredBy": [
        ]
    },
]

Where each {} object represents a post object.

On the client side, you could then check if the likedBy list contains the currently logged in user and proceed with the result as you see fit. Same for stars and any other of these properties a post might have.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM