Front-End centric API: should it use dictionaries or mix-in names and other properties into each response?

We’re designing a web front-end (FE) centric (you may call it BFF) API for a PLM (product lifecycle management) system. Our case specifics is that for many types of entities the number of members is quite low, for example there’re less than 1k users, less than 1k seasons, less than 1k materials and so on. There’re two ways on API interface we’re currently considering.

Let’s say we need to return a product. A product response should contain info on a single product. A product page has to display properties of a product, but also “links” or you may say “foreign keys” in terms of relational DBs (which isn’t our case, it’s just to give a cleaner picture) to other entities, for example – a user who created the product, materials used to create a product and so on.

Let’s get to the options finally:

1. Ids + dictionaries

Given that there’re not many (less than 1k) users and materials, FE can load all users and materials when the app is starting (web page loading) and then reuse these “dictionaries” throughout its runtime. In this case the response for a product would look like this:

  productId: "123",                      // product's prop.
  productName: "New product",            // product's prop.
  productSize: "XXXL",                   // product's prop.
  createdByUser: "234",                  // "linked" prop.
  updatedByUser: "345",                  // "linked" prop.
  contiansOfMaterials: ("m123", "m234")  // "linked" props.

2. All in one

Another option is to return everything in one call. My example would look like the following in this case:

  productId: "123",                      // product's prop.
  productName: "New product",            // product's prop.
  productSize: "XXXL",                   // product's prop.
  createdByUser: {
    id: "234",
    name: "John Doe"
  updatedByUser: {
    id: "345",
    name: "Adam Smith"
  contiansOfMaterials: ({
    id: "m123",
    name: "Cotton"
  }, {
    id: "m234",
    name: "Silk"

So, the question is which approach is better? I understand that there’s no silver bullet and each case is unique in some way or another, and this is why I tried to get as close to a real example as possible. Again, even for this particular case there’re pros and cons to each approach. What I see at the moment is the following:

Option #1 (dictionaries)

  • (+) Less payload for each request

  • (+) Less complex and more performant implementation of back-end (you don’t need to search for a material’s data every time a product is requested)

  • (-) More complex and less performant implementation of front-end (you basically offload this piece of work to FE)

  • (-) If some dictionaries overgrow certain limit (let’s say 10k kinds of materials) FE performance may suffer. For example, phones may offload the page from RAM too often due to memory consumption

  • (-) FE load time may increase (we need some time to load dictionaries anyway)

Option #2 (all in one)

  • (+) More simple FE implementation

  • (-) Larger request payloads with significant amount of data being just duplications (let’s say you’re reviewing product of a single user – you’ll receive the same user name for each request)

  • (-) FE and BE coupling is higher as the contract is much more detailed

I’d much appreciate your thoughts on both approaches, mostly interested in other pros and cons (I definitely missed some). Also, issues and experiences you faced when implemented it in one way or the other in a real world, would be very useful.