浏览代码

Create ChainP middleware that handles promised based middleware chain

Tatiana Inama 7 年之前
父节点
当前提交
3a0e5970d4
共有 3 个文件被更改,包括 29 次插入13 次删除
  1. 19 1
      ktchn/src/promise-all-middleware.ts
  2. 7 6
      ktchn/src/recipes/controller.ts
  3. 3 6
      ktchn/src/recipes/routes.ts

+ 19 - 1
ktchn/src/promise-all-middleware.ts

@@ -5,12 +5,30 @@ export interface IMiddleware {
   (req: Request, res: Response, next: NextFunction): Promise<any>
 }
 
+export interface ChainedMiddleware {
+  (req: Request, res: Response, next: NextFunction): (result: any) => Promise<any>
+}
+
 const piddleware = (middlewares: IMiddleware[]) => (req: Request, res: Response, next: NextFunction): void => {
   middlewares.reduce((middlewaresChain, currentMiddleware) => {
     return middlewaresChain.then(x => currentMiddleware(req, res, next))
   }, Promise.resolve([])).then(results => { // results would be ever necessary ?  
+    console.log("results", results)
     next();
   }).catch(error => next(error));
 }
 
-export default piddleware;
+const chainP = (middlewares: ChainedMiddleware[]) => (req: Request, res: Response, next: NextFunction): void => {
+  middlewares.reduce(async (middlewaresChain, currentMiddleware) => {
+    const result = await middlewaresChain;
+    return await currentMiddleware(req, res, next)(result);
+  }, Promise.resolve()).then(results => { // results would ever be necessary ?  
+    res.json(results)
+  }).catch(error => next(error));
+}
+
+export default piddleware;
+
+export {
+  chainP,
+};

+ 7 - 6
ktchn/src/recipes/controller.ts

@@ -3,7 +3,7 @@ import { Recipe, IIngredient, IngredientSuggestion } from './model';
 import { IMongoService } from '../mongo';
 import { FilterQuery } from 'mongodb';
 import Scrape from './scrape/index';
-import { ISubRecipe, ScrapedRecipe } from './model';
+import { ScrapedRecipe } from './model';
 import Ingredient from '../ingredients/model';
 
 function validRecipe(data: any): Promise<Recipe> {
@@ -14,6 +14,8 @@ function validRecipe(data: any): Promise<Recipe> {
 
 type Controller<T> = (db: IMongoService) => (req: Request, res: Response, next: NextFunction) => Promise<T>;
 
+type ChainedController<T, U> = (db: IMongoService) => (req: Request, res: Response, next: NextFunction) => (result: T) => Promise<U>;
+
 const getSuggestions = (db: IMongoService) => async function(ingredient: IIngredient): Promise<IngredientSuggestion> {
   const suggestions = await db.find<Ingredient>({$text: {$search: ingredient.name}}, { score: { $meta: "textScore" } });
   return {
@@ -22,7 +24,7 @@ const getSuggestions = (db: IMongoService) => async function(ingredient: IIngred
   }
 }
 
-const scrape: Controller<void|ScrapedRecipe> = (db) => (req: any, res, next) => {
+const scrapeRecipe: ChainedController<void, ScrapedRecipe> = (db) => (req) => () => {
   return Scrape(req.body.url)
     .then(async scrapedRecipe => {
       const recipeIngredients = await Promise.all(scrapedRecipe.ingredients.map(async subGroup => {
@@ -32,12 +34,11 @@ const scrape: Controller<void|ScrapedRecipe> = (db) => (req: any, res, next) =>
           ingredients: subgroupIngredients
         });
       }));
-      res.json({
+      return {
         ...scrapedRecipe,
         ingredients: recipeIngredients
-      })
+      }
     })
-    .catch(error => console.log(error));
 }
 
 const save = (db: IMongoService) => ({ body }: Request, res: Response, next: NextFunction): Promise<any> => {
@@ -91,7 +92,7 @@ const getByIngredients = (db: IMongoService) => ({ query, params }: Request, res
 
 export {
   save,
-  scrape,
+  scrapeRecipe,
   getById,
   get,
   getAll,

+ 3 - 6
ktchn/src/recipes/routes.ts

@@ -1,10 +1,8 @@
 import { Request, Response, Router, NextFunction } from "express";
-import Scrape from "./scrape";
-import { Recipe } from './model';
-import { save, get, getById, getAll, getByIngredients, scrape } from './controller';
+import { save, get, getById, getAll, getByIngredients, scrapeRecipe } from './controller';
 import MongoClient from 'mongodb';
 import { mongoService, IMongoService } from '../mongo';
-import piddleware from '../promise-all-middleware';
+import piddleware, { chainP } from '../promise-all-middleware';
 
 class RecipeRoutes {
   public router: Router;
@@ -23,9 +21,8 @@ class RecipeRoutes {
     this.router.get("/query/", piddleware([get(this.RecipeDB)]));
     this.router.get("/ingredients/", piddleware([getByIngredients(this.RecipeDB)]));
     this.router.get("/id/:id", piddleware([getById(this.RecipeDB)]));
-    
     this.router.post("/", piddleware([save(this.RecipeDB)]));
-    this.router.post("/scrape", piddleware([scrape(this.IngredientDB)]));
+    this.router.post("/scrape", chainP([scrapeRecipe(this.IngredientDB)]));
   }
 
   private logData(req:Request, res:Response, next: NextFunction): void {