【问题标题】:Angular frontend with REST backend: entity design for CRUD-operations带有 REST 后端的 Angular 前端:CRUD 操作的实体设计
【发布时间】:2021-06-11 16:22:00
【问题描述】:

我正在为单页应用程序使用 Angular 12 前端、Spring REST 后端。

如果实体的字段对于每个 CRUD 操作都不同,那么在 Angular 中创建实体的最佳方法是什么?

让我们以一个用户对象为例,每个请求类型都有不同的字段:

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;
}

如您所见,Id 可以根据请求是可选的,hobby 的字段类型可以是 object 或 number。

像上面那样在 Angular 中保留三个对象更好,还是应该像这样创建一个“通用”对象:

POST-Request 的数据:

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

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

从长远来看,Angular 12 有什么更好的方法?

提前谢谢

【问题讨论】:

    标签: angular typescript rest spring-rest


    【解决方案1】:

    如果没有更多背景知识很难回答这样的问题,但出于几个原因,第一个解决方案似乎是显而易见的选择,

    1. 您更清楚地定义了需要为每种请求类型提供哪些信息。开发人员不必弄清楚在每个请求中放入什么内容。

    2. TypeScript 将强制他们在每个请求中发送正确的数据类型。 爱好之类的东西:爱好[] | number; 您是在告诉 TypeScript,这两种类型通常对请求都有效,但事实并非如此。

    【讨论】:

    • 谢谢,我想我会选择第一种方法
    【解决方案2】:

    我的结构方式不是基于这些使用的 HTTP 方法,而是它们在上下文中的含义。

    基于此,我看到了两个真实的实体:

    1. 一个用户
    2. 创建用户的请求

    基于此,这将是我将遵循的约定:

    export type User {
       id: string;
       firstName: string;
       lastName: string;
       hobbies: Hobby[];
    }
    
    export type CreateUser = Omit<User, 'id'>;
    

    【讨论】:

    • 谢谢 - 这几乎是我所需要的,但它不包括提供的示例中的不同字段类型:显示用户的 GET 请求会将爱好显示为对象,同时创建用户,我只会发送爱好 id 而不是完整的对象。
    【解决方案3】:

    在我看来,UserGet、UserPost 和 UserPut 非常相似,现在您可以做一些事情,例如创建一个服务来生成对象并省略您想要的字段,但我不会在合同上这样做 Hobby[] | number (接口),是在应用程序的其他地方发生奇怪突变的可靠方法,我通常倾向于对参数、范围变量或泛型类(例如Subject&lt;number | string&gt; 或类似的东西)执行此操作。基本上,我会使用通用接口作为基础:

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

    那么你可以为每个单独的接口:

    export interface User implements UserBase<Hobby> {};
    
    export interface UserRequest implements UserBase<number> {};
    
    export interface Hobby {
      id: string;
      hobby: string;
    }
    

    当然在各自的文件中。

    您还可以从接口名称中删除 Http 动词,接口/对象应根据它们的名称命名,并且不应包含使用它的操作,因为如果在其他地方使用它会变得非常混乱应用程序,但用于不同的目的,但这是我的意见。

    【讨论】:

      猜你喜欢
      • 2013-02-02
      • 2014-04-12
      • 2021-03-13
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 2016-11-21
      • 2016-09-19
      • 1970-01-01
      相关资源
      最近更新 更多