The art of representing objects and generating JSON responses

As I dive into building a web application using NextJS, a versatile framework for both API and user interface implementation, I find myself pondering the best practices for modeling and handling JSON responses.

Key Points

  • In my database, models are stored with foreign keys to establish relationships like many-to-many, one-to-many, and one-to-one.
  • I am currently utilizing TypeScript, a programming language that supports interfaces.
  • These interface declarations can be accessed from both the front end and back end of the application.
  • When retrieving a model with a foreign key from the backend (API), I use an interface where the foreign key is defined as a string.
  • For the frontend, rather than simply giving a reference to the object in the foreign key, I aim to include the related object directly within the JSON response.

The Challenge
To achieve this desired pattern, I find myself needing to define two similar interfaces: one for a basic shallow reference (foreign key) and another for embedding the related object.

For instance, consider a Blog Post model (Post):

interface Post {
    id: string;
    creatorId: string;
}

And a User model (User):

interface User {
    id: string;
    name: string;
}

To fetch data from the database, I use the Post interface that mirrors its storage structure. However, to send nested objects to the frontend, I require a model like:

interface PostWithNested {
    id: string;
    creator : User;
}

resulting in a JSON structure such as:

{
    "id": "X",
    "creator": {
        "id" : "Y",
        "name": "Z";
    },
}

Consider this example snippet from the API where database parsing necessitates the use of an interface:

...
const postsRepository = getRepository(Post); // contains shallow reference
const singlePost : Post = await postsRepository.findById(X);
// Embedding related object
const postWithNested : PostWithNested = {
    id : singlePost.id,
    user : userInstance,
}

res.status(200).json({post : postWithNested }

Is there a way to avoid declaring two almost identical interfaces that differ mainly in their treatment of related objects?

Answer №1

If you want to establish an interface called Post that includes an optional creator, here's how you can do it:

interface User {
    id: string;
    name: string;
}
interface Post {
    id: string;
    creatorId: string;
    creator?: User; // This field will only be populated if data is available
}

When the API provides data for creator, it will automatically populate. Otherwise, in your Post object, it will remain unset. You can check out the logs here.

Here is how you can integrate it into your code:

const postsRepository = getRepository(Post);
const singlePost : Post = await postsRepository.findById(X);

res.status(200).json({post : singlePost })

Similarly, in a one-to-many relationship situation where one user has multiple posts, you can use this interface structure:

interface User {
    id: string;
    name: string;
    posts?: Post[]; // Holds multiple posts associated with this user
}
interface Post {
    id: string;
    creatorId: string;
    creator?: User; 
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using RestTemplate to retrieve JSON data with GET request

Currently, I am working on developing a test unit for the GET method that relies on a JSON payload to retrieve results based on the provided data in JSON format. This is what I have attempted: User user = new User(); user.setUserId(userId); ResponseEnt ...

Display a loading spinner (circle) while fetching JSON data from a given URL

Just starting out with Android Studio and trying to fetch JSON data from a URL using Volley. It's all working fine, but I'd like to add a loading circle while retrieving the JSON data. If anyone could help me with my code: package imo.meteoir ...

What method is the most effective for retrieving the prior slug name in NextJS?

Looking for Help with Retrieving postID? Greetings! I am currently working on a basic post detail page using NextJS. My URL structure is: [postID]/[title].tsx On the post detail page, I need to fetch the post's data based on the postID, which is hig ...

Evaluating observables in .pipe angular 8 jasmine

In my component, I have a subscription to triggerRuleExecutionService which is triggered by another component using next(). Within the pipe, I am using switchMap to make an HTTP service call and retrieve data from the database. this.ruleExecutionService ...

The utilization of dynamic server resources was necessary as the page could not be rendered statically due to the utilization of `nextUrl.searchParams` in Next.js version 14

I find myself in dire straits and need assistance. Currently, I am working on a full stack application with Next.js version 13. I have successfully created an API that works flawlessly in development mode (npm run dev). However, the issue arises when I tr ...

Inaccurate recommendations for type safety in function overloading

The TypeScript compiler is not providing accurate suggestions for the config parameter when calling the fooBar function with the 'view_product' type. Although it correctly identifies errors when an incorrect key is provided, it does not enforce t ...

Tips for filtering data in JSON results within a Java servlet

I need to filter records by gender that are in a JSON response. I have a method in my DAO class that returns JSON data, so I want to parse the contents to filter by gender type. String results = bedsBean.allBedsInJson(); System.out.println(results); Th ...

Javascript Library Issue: "Implicitly Declared Type 'Any' Error"

I am currently in the process of developing a JavaScript library that will interact with an API. My goal is to create a module that can be easily published on npm and utilized across various frameworks such as Angular or React. Below is the code snippet fo ...

Is there a way to retrieve the chosen value from an ion-alert radio alert?

async showAlertRadio(heading:string){ const alert = await this.alertCtrl.create({ header: heading, inputs :[ { name : 'Radio 1', type: 'radio', label: 'Radio 1', ...

Typescript and RxJS: Resolving Incompatibility Issues

In my development setup, I work with two repositories known as web-common and A-frontend. Typically, I use npm link web-common from within A-frontend. Both repositories share various dependencies such as React, Typescript, Google Maps, MobX, etc. Up until ...

Retrieving a JavaScript variable's value in Selenium with Python

rwdata = driver.find_elements_by_xpath( "/html/body/div[2]/div/div/div/form[2]/div[2]/table/tbody") This table contains the value of variable r as text/javascript type. for r in rwdata: print(r.text) if r.text != "Booked": ...

Unexpected Union Type Return from Apollo Server

When I call my resolver to return a union type (either a User or an object with a message key and value of type String, such as my UserNotFoundError type), it always comes back with "__typename": "User". Why is this happening and how ca ...

Guide to utilizing the app.locals parameter in JavaScript?

Currently I am in the process of developing a node.js application. In my app.js file, I have loaded a JSON file as app.locals.parameter and now I am attempting to utilize it in my index.hbs. Let's assume: app.locals.componentData = require('./m ...

Developing interconnected dropdowns in Angular 8 for input fields

Imagine we have a list of names structured like this: nameSelected: string; names: Name[ {firstName: 'John', middleName: 'Danny', lastName: 'Smith'}, {firstName: 'Bob', middleName: 'Chris', lastN ...

core.js encountered an error at line 6237: Unable to assign value to property 'area' as it is undefined

HTML: I have created a form but encounter an error when clicking the submit button. Can someone please assist me in identifying the issue? <h3 class="page-header">Operator Form</h3> <div class="outer-container"> <form class="form-s ...

Encountering ExpressionChangedAfterItHasBeenCheckedError during ngOnInit when utilizing Promise

I have a simple goal that I am working on: I want to display data obtained from a service in my component. This is how it used to work: In my component: ... dataSet: String[]; ngOnInit(){ this._service.getDataId().then(data => this.dataSet = da ...

Error: Unexpected symbol "<" found in JSON at position 4

A JSON syntax error occurred at position 4, causing an Unexpected token < error message. The issue seems to be with the JSON.parse function in the jQuery library. Despite searching online and trying various solutions, I have been unable to resolve this ...

Using the .val() function to retrieve values from a list in PHP

I am attempting to retrieve data from a list (listDIV) to display in my form (formDIV). The data is fetched from a database using JSON. However, I keep encountering the error "Database error, please select something else." in my textarea field, indicating ...

parsing nested JSON from an HTTP GET request using Go's unmarshaling function

After reviewing the article about Unmarshaling nested JSON objects, I am still uncertain about how to manage the following json: { "input":{ "lat":1234, "lon":1234 }, "stuff":[ { "soc":"510950802051011", "bbox" ...

Accessing JSON data through crawling may trigger an "Invalid access" warning

Currently extracting data, I came across this base URL After inspecting chrome's developer tools - Network tab, I found the following URL: international?Adt=1&Chd=0&ECITY1=HKG&ECITY2=ICN&Fa…019.03.13.&TRIP=RT&W ...