项目

服务代理

从 Angular 应用调用 REST 端点是很常见的需求。我们通常会创建与服务器端控制器对应的服务,以及与 DTO 对应的接口来与服务器交互。这往往需要手动将C#代码转换为TypeScript版本,即使不算无法容忍,也相当令人困扰。

为避免手动操作,我们可能会使用类似 NSWAG 的工具来生成服务代理。但NSWAG存在一些缺点:

  • 它会生成单个.ts文件,随着应用增长文件会过于庞大。而且这种单文件模式不符合ABP的**模块化架构**
  • 坦率地说,生成的代码有些不够优雅。我们希望生成的代码看起来像是人工编写的
  • 由于swagger.json无法准确反映后端服务的方法签名,NSWAG也无法在客户端准确还原这些签名

ABP提供了一个能暴露服务端方法契约的端点。当运行generate-proxy命令时,ABP CLI会向该端点发起HTTP请求,并生成更匹配的TypeScript客户端代理。它会按命名空间组织文件夹结构,添加桶状导出,并在Angular服务中准确反映方法签名。

开始前请确保通过dotnet run启动后端应用。Visual Studio存在已知限制,请勿使用其内置Web服务器运行项目。

在Angular应用的根目录运行以下命令:

abp generate-proxy -t ng

注意

  • 若使用NX,请注意基于Angular原理图的ABP包可能无法正常工作。我们为NX代码库提供了专用包@abp/nx.generators,建议使用该生成器。具体说明请参考相关章节
  • 不带参数的命令仅会为当前应用服务生成代理,并放置在默认Angular应用中。可通过多个参数调整此行为,详见详情

生成的文件将位于目标项目根目录的proxy文件夹内。

通过generate-proxy生成的文件

每个文件夹将包含对应命名空间中定义的模型、枚举和服务,并配有桶状导出文件(即index.ts)以简化导入。

命令通过读取angular.json文件识别应用/库根目录。请确保已将目标项目设为defaultProject或通过--target参数指定。这也意味着您可以使用monorepo工作区。

Angular项目配置

若项目创建版本为3.1或更高,可跳过此部分,相关配置已预置。

针对v3.1之前创建的解决方案,按以下步骤配置Angular应用:

  1. 在Angular项目的devDependencies中添加@abp/ng.schematics包。在Angular应用根目录运行:
npm install @abp/ng.schematics -D
  1. 在应用项目的/src/environments/environment.ts中添加rootNamespace属性(需将MyCompanyName.MyProjectName替换为.NET项目的根命名空间):
export const environment: Config.Environment = {
  // 其他环境变量...
  apis: {
    default: {
      rootNamespace: "MyCompanyName.MyProjectName",
      // 其他环境变量...
    },
  },
};
  1. [可选] 在tsconfig.base.json中添加以下路径配置,方便导入代理:
{
  // 其他TS配置...
  "compilerOptions": {
    // 其他TS配置...
    "paths": {
      "@proxy": ["src/app/proxy/index.ts"],
      "@proxy/*": ["src/app/proxy/*"]
    }
  }
}

proxy文件夹的生成位置和上述路径可能因项目结构而异。

generate-proxy参数说明

  • module或-m: 后端模块名称。默认为app。对应api/abp/api-definition响应中定义模块的对象键。例如要为PermissionManagement生成代理,应传入permissionManagement
  • apiName或-a: 后端API名称(即remoteServiceName)。在选定模块中定义(位于api/abp/api-definition响应)。属性键名为remoteServiceName。例如PermissionManagement应传入AbpPermissionManagement
  • source: 用于解析API定义URL和根命名空间的Angular项目源
  • target: 放置生成代码的Angular项目目标。例如设为permission-management时,路径将类似(npm/ng-packs/packages/permission-management)
  • entryPoint: 在目标项目中创建生成代理的目录。目录结构为permission-management/proxy/src/lib/proxy,其中permission-management是target值。若想为生成代理创建文件夹,有两种选择:将entryPoint设为proxy,或在project.json中将sourceRootpackages/permission-management/src改为packages/permission-management/proxy/src
  • serviceType: 生成代理的服务类型。可选值为applicationintegrationall。默认值为application。开发人员可将服务标记为“集成服务”,若需跳过该服务的代理生成,此设置非常有用。详见集成服务

服务

generate-proxy命令会为每个后端控制器生成对应服务,并为控制器中的每个操作生成方法(实际为函数值的属性)。这些方法通过 RestService 调用后端 API。

每个服务中定义了apiName变量(v2.4+支持)。apiName与模块的RemoteServiceName匹配。该变量会在每个请求中作为参数传递给RestService。若环境中未定义微服务API,RestService将使用默认配置。参见 从应用配置获取特定API端点

服务的providedIn属性设置为'root',因此无需在模块中单独提供。可直接注入使用:

import { BookService } from '@proxy/books';
import { inject } from '@angular/core';

@Component(/* 组件元数据 */)
export class BookComponent implements OnInit {
  private service = inject(BookService);

  ngOnInit() {
    this.service.get().subscribe(
      // 对响应进行处理
    );
  }
}

Angular编译器会从最终输出中移除未被注入的服务。参见可摇树优化提供者文档

模型

generate-proxy命令会生成与后端DTO匹配的接口。@abp/ng.core包中也包含一些核心DTO。这些模型可共同用于反映API结构。

import { PagedResultDto } from "@abp/ng.core";
import { BookDto } from "@proxy/books";

@Component(/* 组件元数据 */)
export class BookComponent implements OnInit {
  data: PagedResultDto<BookDto> = {
    items: [],
    totalCount: 0,
  };
}

枚举

枚举在前端一直难以处理。generate-proxy命令会在单独文件中生成枚举,并从同一文件导出开箱即用的“选项常量”。可如下导入:

import { bookGenreOptions } from "@proxy/books";

@Component(/* 组件元数据 */)
export class BookComponent implements OnInit {
  genres = bookGenreOptions;
}

...并在模板中使用这些选项:

<!-- 为简洁起见已简化 -->
<select formControlName="genre">
  <option [ngValue]="null">选择类型</option>
  <option *ngFor="let genre of genres" [ngValue]="genre.value">
    {{ genre.key }}
  </option>
</select>

参阅本文 深入了解服务代理。

ABP NX代理生成器

对于使用NX的项目,@abp/nx.generators包提供无缝集成。该包本质上是为NX代码库量身定制的封装器。

安装 通过以下命令将包添加到项目:

yarn add @abp/nx.generators

使用 运行以下命令使用生成器:

yarn nx generate @abp/nx.generators:generate-proxy
// 或
yarn nx g @abp/nx.generators:generate-proxy

注意: 该生成器参数与标准ABP代理生成器保持一致。

已知限制

当使用Visual Studio通过IIS Express作为Web服务器运行项目时,端点将无法远程访问。这是IIS Express的默认行为,旨在防范网络运行的安全风险。但这会导致代理生成器失败,因为它需要从/api/abp/api-definition端点获取响应。可通过Kestrel提供服务来避免此问题。在项目文件夹中运行dotnet run即可实现。

另请参阅

在本文档中