Je développe les deux côtés. L'API est en nest.js et le front-end en Angular. Les deux parties utilisent typescript et je suis confronté au problème du partage des interfaces, qui devraient être les mêmes. Par exemple ILoginRequest et ILoginResponse. Je veux que les deux projets soient dans des dépôts GIT séparés. Devrais-je utiliser un sous-module GIT avec un troisième dépôt GIT partagé ou créer d'une manière ou d'une autre un paquet npm partagé ou existe-t-il un bon outil pour générer automatiquement des classes (à partir d'une définition swagger) dans le frontend ou autre chose ?
Réponses
Trop de publicités?NOTE : Je suis récemment tombé sur typeorm-entitysharer qui "peut être utilisé pour créer des classes client/serveur basées sur les mêmes entités TypeORM, permettant de les partager". Il vous donne plus de contrôle sur ce que vous voulez partager, vous pouvez jeter un coup d'œil à leur exemple. Je n'ai pas choisi de l'utiliser parce que c'est un peu exagéré pour moi, je suppose. Cependant, c'est ainsi que j'ai structuré mon dernier projet :
J'ai mon frontend et mon backend dans un seul dépôt, mais je suppose que vous pourriez les avoir séparés, mais vous auriez toujours besoin de les garder à côté les uns des autres d'une manière ou d'une autre. La structure des fichiers serait quelque chose comme ceci :
workspace
backend <- repo #1
src
shared <- shared code goes here
proxy.ts
tsconfig.json
frontend <- repo #2
src
proxy.ts
tsconfig.json
Ensuite, dans backend/tsconfig.json
vous présentez
{
...
"paths": {
"@shared/*": [ "src/shared/*" ],
}
}
et en frontend/tsconfig.json
vous présentez
{
...
"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
}
}
también n'oubliez pas de npm i typeorm
dans votre frontend.
Exemple
Disons que j'ai ceci dans backend/src/shared/user.entity.ts
import { PrimaryGeneratedColumn, Column } from 'typeorm';
export class UserEntity
{
@PrimaryGeneratedColumn() id: number;
@Column() name: string;
@Column() password: string;
}
Maintenant, je peux l'utiliser partout comme ça :
import { UserEntity } from '@shared/model/user.entity';
En backend, c'est évident, et en frontend, @shared/model/user.entity
est mis en correspondance avec ../backend/src/shared/model/user.entity
et le import from 'typeorm'
à l'intérieur de l'entité est mis en correspondance avec le paquet fictif.
Ayant été confronté au même problème, j'ai examiné quelques alternatives. Voici ce que j'ai considéré et ce que j'ai choisi :
- Séparer les définitions des entités dans une base de code séparée - potentiellement dans un repo git différent. Le problème ici est que le Nest utilise des décorateurs qu'Angular ne comprend pas. Cela signifierait que je devrais inclure Nest comme une dépendance, ce qui semble être une mauvaise idée, ou créer des décorateurs stub - une perte de temps. Rejeté
- Création d'un paquet de nœuds - mêmes problèmes que le numéro 1. Rejeté
- Copier coller. Les projets backend et frontend ont tous deux un dossier d'entités. Les entités du backend sont classes qui sont décorés avec des décorateurs TypeORM (pour moi). Je les copie dans le répertoire des entités du frontend et les convertit en interfaces car ce que vous obtenez en retour de la bibliothèque httpclient (des objets qui doivent se conformer à l'interface - pas des instances de classe). Adopté
Enfin, en regardant les commentaires, je ne vois pas en quoi GraphQL est utile ici, puisque vous ne tentez pas de tirer parti d'une interface existante - j'aimerais entendre quelqu'un à ce sujet :)
Après avoir passé une journée entière à essayer de faire fonctionner ce système, je suis tombé sur NX/NRWL .
Il s'agit essentiellement d'un CLI avec des outils permettant de structurer correctement votre application. J'ai été capable de le faire fonctionner correctement en une heure environ. Les interfaces partagées dans un mono-repo est la voie à suivre.