在API和前端之间共享接口



我正在发展双方。API位于nest.js中,并在角度为前端。双方都使用打字稿,我面临共享界面的问题,这应该是相同的。例如iloginrequest和iloginresponse。我想在单独的git存储库中两个项目。我应该将git子模块与第三共享的git repo一起使用或以某种方式创建共享的npm软件包,还是有一些好的工具可以自动生成类(从摇摇欲坠的定义)或其他任何东西?

编辑:要从Swagger生成客户代码,请查看OpenAPI-Generator

注意:我最近偶然发现了Typeorm-entitySharer,"可用于基于同一Typeorm实体创建客户端/服务器类,从而可以共享它们。"它使您可以更多地控制要分享的内容,可以看看他们的示例。我没有选择使用它,因为我猜这对我来说有点过大。但是,这就是我结构上一个项目的方式:


我有一个存储库的前端和后端,但是我想您可以将它们分开,但是您仍然需要以某种方式将它们保持在彼此之间。文件结构将是这样的:

workspace
  ├─backend        <- repo #1
  │   ├─src
  │   │   ├─shared <- shared code goes here
  │   │   └─proxy.ts
  │   └─tsconfig.json
  └─frontend       <- repo #2
      ├─src
      │   └─proxy.ts
      └─tsconfig.json

然后在backend/tsconfig.json中您引入

{
    ...
    "paths": {
        "@shared/*": [ "src/shared/*" ],
    }
}

,在frontend/tsconfig.json中您引入

{
    ...
    "paths": {
        "@shared/*": [ "../backend/src/shared/*" ],
        // if you're using TypeORM, this package has dummy decorators
        "typeorm": [ "node_modules/typeorm/typeorm-model-shim.js" ]
        // you can do the same for other packages, point them to dummy paths
        // altirnatively you can route the shared imports through the proxy.ts
        // and replace them in frontend/src/proxy.ts with dummy ones
    }
}

也不要忘记前端中的npm i typeorm

示例

假设我在 backend/src/shared/user.entity.ts

中有这个
import { PrimaryGeneratedColumn, Column } from 'typeorm';
export class UserEntity
{
    @PrimaryGeneratedColumn() id: number;
    @Column() name: string;
    @Column() password: string;
}

现在,我可以在任何地方使用它:

import { UserEntity } from '@shared/model/user.entity';

在后端,很明显,在前端,@shared/model/user.entity被映射到../backend/src/shared/model/user.entity,并且实体内的import from 'typeorm'被映射到虚拟软件包。

浪费了一整天试图使这种工作时,我遇到了nx/nrwl。

基本上只是一个具有工具的CLI,可以帮助您正确构建应用程序。我能够在大约一个小时内使其正常工作。单声波中的共享接口是要走的方式。

遇到了相同的问题并查看了一些替代方案。这是我考虑的和我选择的:

  1. 将实体定义分为单独的代码库 - 可能在不同的git回购中。这里的问题在于,Nest使用Angular不了解的装饰器。那意味着我必须将巢穴作为一个依赖性,这似乎是一个坏主意或创建存根装饰的人 - 浪费时间。被拒绝
  2. 创建一个节点软件包 - 与#1相同的问题。被拒绝
  3. 复制粘贴。后端和前端项目都有一个实体文件夹。后端的实体是,都装饰着typeorm装饰器(对我来说)。我将它们复制到前端的实体目录,然后将它们转换为接口,因为您从httpclient库中返回的内容(应该符合接口的对象 - 而不是类实例)。采用

最后,查看评论,我看不到GraphQl在这里有何帮助,因为您没有尝试利用现有界面 - 希望听到某人的消息:)

最新更新