Design of entities for CRUD operations in Angular frontend with REST backend

Currently, my setup involves an Angular 12 frontend and a Spring REST backend for a Single Page Application.

I'm facing a challenge in creating entities in Angular when the fields of an entity vary for each CRUD operation. For instance, let's consider a User object with different fields required for each request type:

export interface UserGet {
   id: string;
   firstName: string;
   lastName: string;
   hobbies: Hobby[];
}

export interface UserPost {
   firstName: string;
   lastName: string;
   hobbies: number[];
}

export interface UserPut {
   id: string;
   firstName: string;
   lastName: string;
   hobbies: number[];
}

export interface Hobby {
   id: string;
   hobby: string;
}

In this scenario, the ID may be optional depending on the request, and the field type of 'hobby' can fluctuate between object and number.

Should I manage three separate objects in Angular as shown above, or would it be more practical to create a single "common" object like the following?

Data structure for POST-Request:

export interface UserCrud {
   id?: string;
   firstName: string;
   lastName: string;
   hobbies: Hobby[] | number;
}

export interface Hobby {
   id: string;
   hobby: string;
}

Which approach is better for long-term maintenance within the context of Angular 12? Any insights will be greatly appreciated.

Answer №1

Without a deeper understanding of the context, it's challenging to provide a definitive answer. However, the first solution appears to be the most logical choice for several reasons:

  1. By clearly defining the required information for each type of request, developers will have a clear roadmap and won't need to guess what data to include in each request.

  2. TypeScript will ensure that the correct data types are being sent with every request. For example, using hobbies: Hobby[] | number; may suggest to TypeScript that both types are acceptable for all requests, which may not be accurate.

Answer №2

In considering the structure of this scenario, my approach focuses less on the specific HTTP methods being used and more on their contextual significance.

Upon reflection, it appears that there are two distinct entities at play:

  1. An individual user
  2. The action of creating a new user

Given these observations, I would adhere to the following convention for organization:

export type User {
   id: string;
   firstName: string;
   lastName: string;
   hobbies: Hobby[];
}

export type CreateUser = Omit<User, 'id'>;

Answer №3

In my view, UserGet, UserPost, and UserPut share many similarities. Currently, there are various approaches you can take, such as creating a service to generate the object and exclude certain fields. However, I advise against defining Hobby[] | number within a contract (interface) as it could lead to unexpected mutations in other parts of the application. Personally, I prefer setting these constraints on parameters, scoped variables, or generic classes like Subject<number | string>. For a more structured approach, I suggest using a generic interface as the foundation:

export interface UserBase<TValue> { 
 id?: string;
 firstName: string;
 lastName: string;
 hobbies: TValue[];
}

You can then create separate interfaces for each specific case:

export interface User extends UserBase<Hobby> {};

export interface UserRequest extends UserBase<number> {};

export interface Hobby {
  id: string;
  hobby: string;
}

These should be stored in their respective files.

Furthermore, consider omitting the HTTP verb from the interface name. Interfaces and objects should be named based on their purpose, without linking them directly to a specific operation. This simplifies their usage and prevents confusion if they are repurposed elsewhere in the application – at least, that's my perspective.

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

Is it possible to utilize an XML format for translation files instead of JSON in React Native?

I'm in the process of creating a react native application using the react i18next library. For translations, I've utilized XML format in android for native development. In react native, is it possible to use XML format for translation files inste ...

encountering difficulties calling setAttribute within a function

I am encountering an issue while attempting to use setAttribute() within toggleDiv(). My IDE does not seem to recognize the function and is throwing an error. How can I resolve this problem so that the function is recognized? This specific case relates t ...

Angular 4: Exploring the Contrasts between ngDoCheck and ngAfterViewChecked

Within the context of Angular 2+, it appears that both ngDoCheck and ngAfterViewChecked have a similar purpose. It is noted that ngDoCheck is invoked whenever change detection is activated, which occurs upon a change in the View. According to the documenta ...

Can a Typescript type alias be altered in real time?

Currently, I am developing an Angular library that will function as an API client. The challenge I am facing is that some of the applications utilizing this library are configured with an HttpInterceptor to automatically transform date strings into JavaScr ...

What is the best way to dynamically import two css frameworks in React?

Currently, I am involved in a project that requires me to incorporate a button for toggling between Bootstrap and Foundation at the request of my client. After exploring several alternatives, I have determined that utilizing hooks to manage the state of e ...

Setting up Angular 4 with TailwindCSS

Can TailwindCSS be configured with Angular (4+)? I am willing to eject the Angular project in order to make webpack configuration accessible. However, I am uncertain about what needs to be included in the webpack.config.js file to ensure that TailwindCSS ...

The inclusion of an XSRF-TOKEN using an HTTP Interceptor results in a 400 Error Request

Implementing XSRF-TOKEN to enhance security and prevent XSRF attacks as I pass a JWT through a cookie for my Angular application. Below is the structure of my HttpInterceptor. intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEv ...

Exploring Angular: Understanding Events and Addressing the Error Message "subscribe is not a function"

Recently, I delved into the basics of Angular 4 and encountered a roadblock while trying to listen to an emitted event. Let me share a simple example that demonstrates the issue: DateSenderComponent is sending out the current date to be handled by its par ...

Trouble locating feature module routes in Angular2

Trying to wrap my head around Angular2 routes. Here's the plunker link for reference: This. I'm facing an issue where it can't seem to locate the \heroes or \hero\:id route specified in the heroes-routing-module. Each time the ...

Passing data in Angular 4 with eventEmitter across multiple layers of components

Struggling with a challenge in Angular and need some guidance. I am currently working with Angular 4 and here is the scenario: The app.component.html file contains a wrapper div that I want to be able to change its color by adding a class to it. However ...

After each save, gulp-typescript is emitting errors, however, it works without any issues upon subsequent saves

I'm facing some uncertainty regarding whether the issue I'm encountering is related to gulp, typescript, or Angular 2. Currently, I am using Angular 2 Beta 6. Here is an example of my typescript gulp task: var tsProject = p.typescript.createPr ...

The properties defined in the typescript model become inaccessible once the data is transferred to a different webpage

I've created a TypeScript model within my Angular application and initialized an object with that model. However, when passing the object through routing to the second component (UserComponent), the associated types are not available as shown in the i ...

Increasing the font size of the mdToolTip in Angular2 Materials

Recently, I've been trying to adjust the font size in mdToolTip. While looking through the pre-themes CSS, I came across this class: .mat-tooltip { background: red; font-size: 50px; } However, it seems to be ignoring the font-size syntax. Can any ...

Guide for building a Template-driven formArray in Angular

I am currently implementing a fixed number of checkboxes that are being bound using a for loop. <ul> <li *ngFor="let chk of checkboxes"> <input type="checkbox" [id]="chk.id" [value]="chk.value&q ...

Encountering the message "Error: Unused file" while executing a test for a recently added type definition

In contributing to the DefinitelyTyped project, I recently introduced a new type definition for the hyphen library. The code can be found here. Unfortunately, running the test script npm run test hyphen resulted in the following error message: C:\My ...

Encountering deployment problems with React and TypeScript involving router on Github Pages

After successfully running locally, I encountered a 404 error when deploying the website using "npm run deploy." My application is built with React and TypeScript, utilizing react-router-dom BrowserRouter for navigation between pages. I've spent 7 h ...

Issues arise when attempting to construct an angular docker image

After attempting to create an angular docker image, I encountered the following error message following the execution of npm run build --prod: executor failed running [/bin/sh -c npm run build --prod]: exit code: 1 I am seeking clarification on this iss ...

The password field value in an Angular form is not defined

After making some modifications to a sign-in template that worked perfectly before, I encountered an error when trying to submit the signup form. The error message reads as follows: ERROR TypeError: Cannot read property 'value' of undefined Here ...

The 'Content-Type' header cannot be defined for HTTP GET requests

I am currently working on setting up my GET requests to include the specific header: Content-Type: application/json Based on information from the documentation, I need to make the following adjustment: To customize these defaults, you can add or remov ...

Protecting AWS Cognito User Pool and Client ID in a static webpage

According to the documentation from AWS (User Pool App Settings): Developers are responsible for securing app client IDs and secrets to ensure only authorized client apps have access to unauthenticated APIs. Is there a method to authenticate in a secur ...