Async et contrôleurs

Async vient de changer ma façon de coder. Je découvre une nouvelle façon de manier les promesses avec classe et rendre mon code plus concis. Je vous ai parlé il y a peu de mon node starter qui propose des décorateurs pour facilement spécifier des routes au niveau d'une classe de contrôleur. J'ai modifié le projet pour lui permettre de profiter de async. Voyons ça en détail.

Le module qui s'occupait de charger dynamiquement les contrôleurs dans le dossier routes reprend le travail du décorateur @routes qui n'existe plus. On gagne déjà en clarté car on peut se passer de décorer un contrôleur qui n'a aucune option particulière à spécifier. Mais surtout, j'ai rajouté un contrôle au niveau du retour de la méthode appelée lors de l'accès à une route, et si elle retourne une promesse, alors je renvoie une réponse pré-formatée.

Avant nous avions ceci :

@routes({
  middlewares: authMiddleware
})
export default class Accounts {  
  @get({ route: '/accounts' })
  getAccounts (req, res) {
    accountsFetcher.get({ user: req.user })
      .then(accounts => res.json(accounts.map(account => {
        delete account.credentials;
        return account;
      })))
      .catch(err => res.status(500).send(err));
  }
}

Ainsi, dans chaque méthode, il faut prévoir d'utiliser la bonne méthode de res pour renvoyer un string ou un json, et formatter de façon verbeuse le retour d'une erreur.
Maintenant j'écris ceci de cette façon :

@middlewares(authMiddleware)
export default class Accounts {  
  @get({ route: '/accounts' })
  async getAccounts (req, res) {
    const accounts = await accountsFetcher.get({ user: req.user });

    return accounts.map(account => {
      delete account.credentials;
      return account;
    });
  }
}

Je ne me préoccupes plus des erreurs, elle seront transformées automatiquement en réjections et envoyées au bon format au client. Et je me contente juste de retourner un objet ou un string. Si j'avais voulu renvoyer une erreur spécifique, j'aurais pu utiliser try/catch :

@middlewares(authMiddleware)
export default class Accounts {  
  @get({ route: '/accounts' })
  async getAccounts (req, res) {
    try {
      const accounts = await accountsFetcher.get({ user: req.user });
    } catch (e) {
      throw new RoutingError('No account found', 404);
    }

    return accounts.map(account => {
      delete account.credentials;
      return account;
    });
  }
}

Alors, ça vous donne pas envie de découvrir toutes les nouveautés d'ECMAScript tout ça ?

Hadrien

Hi, I'm a french Web Lead Developer, Front End Architect from Toulouse, France. I've worked for 7 years for Overblog then 2 years with AngularJS. Now, I'm a great fan of Aurelia.io.

Toulouse, France https://hadrien.eu