Coder Social home page Coder Social logo

typestack / routing-controllers Goto Github PK

View Code? Open in Web Editor NEW
4.3K 4.3K 390.0 3.53 MB

Create structured, declarative and beautifully organized class-based controllers with heavy decorators usage in Express / Koa using TypeScript and Routing Controllers Framework.

License: MIT License

TypeScript 99.86% HTML 0.03% JavaScript 0.11%
controllers express-router framework koa-router node-framework router typescript-framework web-framework

routing-controllers's People

Contributors

19majkel94 avatar adenhertog avatar alexproca avatar arthurmelin avatar attilaorosz avatar benjd90 avatar chaowlert avatar d0ck avatar dependabot[bot] avatar diluka avatar efk3 avatar fabiob avatar felipesabino avatar ivanpadavan avatar ivanproskuryakov avatar joshualawson avatar jotamorais avatar kyle-seongwoo-jun avatar lucasltv avatar michallytek avatar mingyang91 avatar nolazybits avatar nonameprovided avatar petermetz avatar phikes avatar pleerock avatar sh3d2 avatar tonypythoneer avatar twittwer avatar yazshel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

routing-controllers's Issues

Why not declare public with HttpError parameters?

Hi @pleerock, I have a question about this.

export class HttpError extends Error {
    httpCode: number;
    message: string;

    constructor(httpCode: number, message?: string) {
        super();
        if (httpCode)
            this.httpCode = httpCode;
        if (message)
            this.message = message;

        this.stack = new Error().stack;
    }
}

Why not do this?

export class HttpError extends Error {

    constructor(public httpCode: number, public message?: string) {
        super();
        this.stack = new Error().stack;
    }
}

When it declare public with httpCode and message, it will auto-pass as instance properties.
Perhaps you have special consideration.

Enabling CORS

I'm having issues enabling CORS. I've tried setting the headers using the @Header decorator

@Get('/')
@Render('home')
@Header("Access-Control-Allow-Origin", "*");
@Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
Index()
{
 //...
}

I've tried using the @UseBefore decorator

@UseBefore(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
})

I've tried setting the middleware in the server.ts file

expressServer.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

Despite trying these 3 methods, I continuously get the error:

esponse to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.

I'm using localhost:80. I've tried on Google Chrome, Firefox, and Microsoft Edge.

Is there something I'm missing?

undefined in a HTTP POST body

I wrote a handler like this. When I use form post or Postman's post, it gets an empty object.
But I use supertest to test it, it seems OK, and get the right body object.

request.body is always undefined.

    @Post("/")
    async saveOne(@Body() data) { //data is {} if not in test
        return await this.todoService.save(data);
    }

test code: PASS

"use strict";
describe("Todo测试", ()=> {
    const expect = require("chai").expect;
    const supertest = require("supertest");
    const request = supertest.agent(`http://localhost:${process.env.LEANCLOUD_APP_PORT}`);

    it("写入对象", (done)=> {
        request.post("/todos").send({"content": `测试数据 - ${new Date()}`}).expect(200).end((e, res)=> {
            expect(res.body).to.be.an("object", "返回对象");
            done();
        });
    });
});

Chrome's POST form submit: FAILED

curl 'http://localhost:3000/todos' -H 'Origin: http://localhost:3000' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: zh-CN,zh;q=0.8' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Cache-Control: max-age=0' -H 'Referer: http://localhost:3000/' -H 'Connection: keep-alive' -H 'DNT: 1' --data 'content=test' --compressed

Postman's curl: FAILED

curl -X POST -H "Cache-Control: no-cache" -H "Postman-Token: e06e03e8-6009-28f6-59cc-0cc72ac6dfbc" -H "Content-Type: application/x-www-form-urlencoded" -d 'content=value to be save&ignore=value to be ignore' "http://localhost:3000/todos"

p.s. just ignore those Chinese characters,there're nothing to do with this issue, consider them just strings

custom error middleware always execute after default

I have custom error middleware to handle errors and decide different way to response. But neither Infinity nor -Infinity I set to the priority option, the default error middleware send the response with status 500 before my error middleware. My error middleware seems to be useless.

how can I solve this?

chai-http and load controllers from folder

Hi,
I'm trying to create a TDD friendly environment for a new project.
I'll use chai-http for testing endpoints.

It seems like the test runner calls the app before the router is defined. not sure.
Does it happen because I'm using the controllers option?

    useExpressServer(this.app, {
      controllers: [__dirname + "/controllers/*.js"],
      middlewares: [__dirname + "/middlewares/global/*.js"],
      useClassTransformer: true,
      defaultErrorHandler: false
    });

If yes, what to do?
If no, what to do?

Related: chaijs/chai-http#143

Action does not handle bluebird promise

I'm trying to return Bluebird promise frin action, and it passes to response without waiting untill it resolves.
This happens because you test instanceof Promise to check that return object is a promise. I think that it is better to test that return object is Thenable or PromiseLike - check that then method exists on returned object.

Only `Get` works with Koa

Hi,

I was very happy to come across this project, and tried to switch my Koa 2.0 app to use it. Turns out that any endpoint that is not a GET just hangs and times out.

@JsonController("/api/analytics")
@UseBefore(myAuthMiddleware())
export default class AnalyticsAPIController {
    @Post("/")
    async noworks(){
        return {yes: "hi"};
    }

    @Get("/")
    async works(){
        return {yes: "hi"};
    }
}

Here is an example of a controller that works:

@JsonController("/api/clients")
export default class ClientsAPIController {
    @Get("/")
    @UseBefore(myAuthMiddlware())
    async getAll(ctx) : Promise<any[]> {
        let res = await clients.logic.getAll();
        return res;
    }

    @Get("/:clientId")
    async get(@Param("clientId") clientId: number) : Promise<any> {
        let client = await clients.logic.get(clientId);
        return client;
    }
}

I'd love to help contribute to this project as well; if you could try to point me in the direction of where you think the error is in the source code, I could take a look/stab.

Global middleware usage fails

Hello,

I am intresting on this project, and I was downloaded your example project (https://github.com/pleerock/routing-controllers-express-demo)

I would like to use Helmet ( https://helmetjs.github.io/ ) with global middleware declaration, but it not works, only works in middleware per-controller, or middleware per-action!

Please check my code:
Working code with middleware per-controller:
let helmet = require("helmet"); @UseBefore(helmet()) export class PostController {....}
but in main app.ts I would like to use:
let helmet = require("helmet"); expressApp.use(helmet());

And after I called some URL, then I got this Error:

Error: Can't set headers after they are sent.
at ServerResponse.setHeader (_http_outgoing.js:367:11)
at dnsPrefetchControl (E:\workspace\adv\node\routing-controllers-express-demo\node_modules\dns-prefetch-control\index.js:9:11)
at call (E:\workspace\adv\node\routing-controllers-express-demo\node_modules\connect\index.js:239:7)
at next (E:\workspace\adv\node\routing-controllers-express-demo\node_modules\connect\index.js:183:5)
at Function.handle (E:\workspace\adv\node\routing-controllers-express-demo\node_modules\connect\index.js:186:3)
at app (E:\workspace\adv\node\routing-controllers-express-demo\node_modules\connect\index.js:51:37)
at Layer.handle [as handle_request] (E:\workspace\adv\node\routing-controllers-express-demo\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (E:\workspace\adv\node\routing-controllers-express-demo\node_modules\express\lib\router\index.js:312:13)
at E:\workspace\adv\node\routing-controllers-express-demo\node_modules\express\lib\router\index.js:280:7
at Function.process_params (E:\workspace\adv\node\routing-controllers-express-demo\node_modules\express\lib\router\index.js:330:12)

Used versions is the lates one in every dependency!

Can you help me what is the problem?

Gzip compression causes empty responses

Hi,
I want to use compression module for Gzip compression, here is my server setup:

    // use gzip compression
    this.app.use(compression());
    // create expressjs application
    useExpressServer(this.app, {
      routePrefix: '/api/v1',
      controllers: [__dirname + '/controllers/*.js'],
      middlewares: [__dirname + '/middlewares/*.js']
    });

My problem is that sometimes i'm getting empty response without the actual data although my controller always returning the data.
Here is my controller code:

  @Get()
  public async getAllUsers(@QueryParam("page") page: number = -1 , @QueryParam("count") count: number = -1, @QueryParam("term") term: string = ''): Promise<Page<User>> {
      let result = await this.getUsers(page, count, term);
      return result.data;
  }

It's only happens when using with compression module, any thoughts?

Signature Mismatch in `MiddlewareInterface`

Consider the following code (note the Request/Response type hints):

export class MyMiddleware implements MiddlewareInterface {
    use(request: Request, response: Response, next?: Function): any {

Compiling throws the following error:

error TS2420: Class 'MyMiddleware' incorrectly implements interface 'MiddlewareInterface'.
  Types of property 'use' are incompatible.
    Type '(request: Request, response: Response, next?: Function) => any' is not assignable to type '{ (request: any, response: any, next?: (err?: any) => any): any; (context: any, next: (err?: any)...'.
      Types of parameters 'response' and 'next' are incompatible.
        Type '(err?: any) => Promise<any>' is not assignable to type 'Response'.
          Property 'status' is missing in type '(err?: any) => Promise<any>'.

This, however, works:

export class MyMiddleware implements MiddlewareInterface {
    use(request: any, response: any, next?: Function): any {

I tracked the issue to the second (Koa) signature in MiddlewareInterface (removing it fixes the above but, obviously, won't make Koa happy). It looks like my code makes the TypeScript compiler think I'm trying to implement the second signature.

While I tried changing/adding signatures in MiddlewareInterface, I couldn't get it to compile.

Support DI in controllers

Hi, this a great library, I had actually rolled my own similar implementation using decorators but this is much more complete solution so I'm looking at migrating to routing-controllers.

My first thought is how canI I inject dependencies into controllers, would you be open to using a DI framework like https://github.com/inversify/InversifyJS/ ??

Flow in returning a promise

What happens in the following code,

@Post("/session")
@NullResultCode(401)
login( @Body({ required: true }) credentials: Object): Promise<Object> {
    return AuthService.getToken(credentials["username"], credentials["password"]);
}

when,

  1. Promise rejects
  2. Promise resolves

Does 401 occur only if I return null?
Is there a way to specify error message for a 401 using promises?

Decorators for middleware ?

Hi

I was wondering if its possible to pass in custom middleware on a route or is it planned ?

or even better, protecting routes using security decorators ? separate library ?

Cannot find module 'routing-controllers'.

Hey there. I'm trying to use routing-controllers in my project; however, after following the instructions in README.md, I get a error TS2307: Cannot find module 'routing-controllers'. wherever I try to use it, e.g. `import { Controller, Param, Body, Get, Post, Put, Delete, Req, Res } from "routing-controllers";``

I'm on node v7 and TypeScript 2.0.10. Not sure what I am doing wrong though... routing-controllers folder is correctly in my node_modules folder.

Dashes in get param value is not accepted

@Get('/:uuid/stuff') public getSomething(@Param('uuid') uuid) { }
When i use the above, and sent a /1234-234234-24324234/stuff (as example)
I get a 'Error' @ HttpError.js:18:22

Request Interceptor

Is it possible to create request interceptor for controller and their actions? My ultimate goal is to add security handler that will check access token.

Duplicated info sections in readme

There is small bug in readme - there are two sections about the same feature - creating instances of classes from action params:

The first one tells you that it's enabled by default and you can disable if you want (which is true) but the second tells about explicit set useClassTransformer: true and later explains that it's enabled by default.

I think that there should be one place for merged info about this feature and links to this place in other places.

Crashed when use some of parameter decorators

When I use @Body(), @Param(), @QueryParam() and etc, program will crash with this error

        var format = Reflect.getMetadata("design:paramtypes", object, methodName)[index];
                                                                                 ^

TypeError: Cannot read property '0' of undefined

routing-controllers 0.6.2
reflect-metadata 0.1.3
node 6.3.1

Bluebird Warning: a promise was created in a handler but was not returned from it

Full text: Warning: a promise was created in a handler at node_modules/routing-controllers/RoutingControllerExecutor.ts:92:35 but was not returned from it, see http://goo.gl/rRqMUw

I know that this is not an issue because promise gets handled by another function. But let's make dat bluebird happy. In my opinion proper promise chaining with return statements it's not a code-style adoption.

As a temporary workaround I've had to disable the forgotten return warning:

Promise.config({
  warnings: {
    wForgottenReturn: false
  }
})

@UseBefore called before all middlewares

Hi @pleerock,

Thanks for your nice lib. I'm trying to run JSON Schema validation for request body using @UseBefore decorator. But once my middleware called, I can't retrive request.body parameter. Is it an expected behavior?

EmailsController.ts

@JsonController("/emails")
export class EmailController {
   
    @Post()
    @UseBefore((request: any, response: any, next: (err?: Error) => void): void => {
        Joi.validate(request.body, schema, (err) => {
            if (err) {
                next(err);
            } else {
                next();
            }
        });
    })
    saveEmail(@Body() email: Email): Email {
        return email;
    }
}

index.ts

import "es6-shim";
import "reflect-metadata";
import {createExpressServer} from "routing-controllers";

let app = createExpressServer({
    routePrefix: "/api",
    controllers: [__dirname + "/controllers/v1/*.js"]
});
const morgan = require('morgan');
const bodyParser = require('body-parser');
const compress = require('compression');

app
    .use(morgan('dev'))
    .use(compress({}))
    .use(bodyParser.json())
    .use(bodyParser.urlencoded({ extended: true }));
app.listen(3000, () => console.log("started"));

If I change @UseBefore to @UseAfter, request will have a body parameter. How can I get an access to body before saveEmail action is called?

One more question: should @UseAfter fail whole request if it returns an error? If I call next(new Error(...)) there it will log an error but still return a result.

call to router controller direct from client

hi,
tanks for the awesome module.

i wonder if its possible to call the controller direct from client side project.

end the controller recognize the caller , and replace the code with "http.get...".
it is possible with decorators?

i think it woud be grate for projects that shared the client side with server side

tanks

Build Table of Contents for this README

This is issue opened for me.

This module is awesome and this document is clear to me.
I want to add Table of Contents for this README. It's convenience for interested developer to read.

KOA Support

I'd like to propose to abstract this to support multiple frameworks and provide out of the box support for koa.

Primary Drivers

  • Express has a big community, but the project hasn't moved in over a year. No major releases, no activity, etc.
  • KOA is faster and lighter.
  • Building on point 1, Express doesn't implement any new ES* features. Generators have been native in node since 6.0 ... KOA has had those for over a year now. KOA.
  • Most of the new new projects I've seen are using KOA which continues to build on point 1. Main reason is lack of support of new features.

Reference

Similar Projects to yours
There are some projects that are similar to your but not near as full feature, here is a list:

Sending raw data is impossible.

Hi!
Thanks for an awesome project! It make writing services in TS a real pleasure.
One bug I came across - even for actions that are marked with a different @ContentType and not inside @jsoncontroller - the result cannot be binary, for example, I cannot send image file.
The reason for it is the following code in ExpressDriver:

 } else {
                    response.send(String(result));
                }

Basically, even if a Buffer is returned - it's converted to string. It's not a correct behavior. At least some sort of escape hatch is needed.

What would you recommend?

Session Error - Parameter user_id is required for request

Here's my code:

@Controller()
export class TestRoutes {
    @Get("/test")
    getTest(@Req() req:Request,@Res() res:Response,@Session("user_id")userId:number) {
        res.send("user:"+userId)
    }
}

Is there any way to prevent the request completely dies when "user_id" from the session is undefined?
I'm getting this error

Parameter user_id is required for request on GET /test

when an anonymous visitor visits the page because "user_id" is not defined in the req.session obj.

I'm not sure if it's related but I have tried custom error handle in your sample and defaultErrorHandler: false in useExpressServer, but nothing works.

Promise<void> returns 404

Hi,

Thank you for the library. I found one case where behavior might not be correct. For example

@Post('/test')    
test() {
    return Promise.resolve();
}

Above will return 404 (even above code was run), even I add EmptyResultCode also doesn't help.
My expectation is it should return 204.

Avoid global state

As for me, having global state like this:

import "./SomeController" // import result affects as a global variable
let app = createExpressServer() // express server implicitly use "SomeController"

is not a good idea, because is handles like global variables. For example, this requries to clear metadata storage before each functional test. I think it could be better, if you made this opt-in, and add ability to explicit pass controllers, interceptors and other citizens to createExpressServer:

import SomeController from "./SomeController"
import SomeInterceptor from "./SomeInterceptor"
let app = createExpressServer(
  SomeController,
  SomeInterceptor
)

or somehow else. What do you think about it?

why will method be executed when the previous method return a result?

when I visit: http://localhost:3000/api/user/all?id=123
the result is '{"id":"all","flag":"getOne"}',but there is a Error: Can't set headers after they are sent.
why will Method:getAll be executed when Method:getOne return a result?

import {Controller, JsonResponse, Param, Get, QueryParam} from "routing-controllers";

@Controller('/user')
export class UserController {

    @Get("/:id")
    @JsonResponse()
    getOne(@Param("id") id:string) {
        console.log('getOne');
        return {id:id,flag:'getOne'};
    }

    @Get("/all")
    getAll(@QueryParam("id") id:number) {
        console.log('getAll');
        return {id:id,flag:'getAll'};
    }
}

Cannot find name 'Promise'

Hi,

it's amazing library, which can help me in my project. Unfortunately, I've problem with correct compilation by tsc.
I receive this error:
node_modules/routing-controllers/middleware/MiddlewareInterface.d.ts(14,60): error TS2304: Cannot find name 'Promise'.

Is it problem with this lib or it's my problem with incorrect configuration ?

Piping Stream to Response Yields Empty Result

Consider the following example of piping a stream (any stream; but my example uses PDF) to the result object:

@Get("/pdf")
public pdf(@Req() req: Request, @Res() res: Response) {
    let wkhtmltopdf = require("wkhtmltopdf");

    res.setHeader("Content-type", "application/pdf");
    wkhtmltopdf("http://localhost/my/app").pipe(res);
}

Unfortunately, the route simply returns Cannot GET /pdf.

The same code, however, works when conventionally registering the route as below.
I wonder if I'm doing something wrong, or if the piping of streams is not yet supported.

app.get("/test", (req: Request, res: Response) => {
    let wkhtmltopdf = require("wkhtmltopdf");

    res.setHeader("Content-type", "application/pdf");
    wkhtmltopdf("http://localhost/projects/proposely").pipe(res);
});

Koa render

Currently in the KoaDriver in the handleSuccess method this.koa.render is called but is undefinded.

I can't find anywhere where koa does rendering, it seems this has been copied from the ExpressDriver because Express handles its rendering, koa uses rendering middlewares that then create the render method on the context.

I am using koa-views as my renderer but getting the following error:

{"name":"TypeError","message":"this.koa.render is not a function","stack":"TypeError: this.koa.render is not a function\n    at KoaDriver.handleSuccess 

I have had a quick play around, and found that changing the call from this.koa.render to options.context.render does cause something to try and load, but timesout without any errors. I haven't looked completely through the routing-controller source to completely understand whats going on.

If anyone could give me some guidance before I dig in I would be more than happy to get this working!

container option in options doesn't work

The container option in useExpressErver function does not work. See below.

import { useExpressServer, useContainer } from 'routing-controllers';
import { Container } from 'typedi';

function setup(app)
    const controllersPath = path.resolve('dist', 'controllers');

    useExpressServer(app, {
      controllerDirs: [ controllersPath ],
      options: { container: Container } // < Does not work
    });

    useContainer(Container); // Works
}

Parameter didn't end with backslash "/"

Given that i have controller like this:

@Get("/charities/:charityId([0-9a-fA-F]{24})/suggests/random")
getRandomSuggest(@Param("charityId", {required: true}) charityId: string): Promise<SomeClass> {
    // doing some awesome stuf
}

If our url is /charities/56b4c81cb88c513400940d5e/suggests/random

Then it will interpreted like this:
current: :charityId is 56b4c81cb88c513400940d5e/suggests/random
the expected 56b4c81cb88c513400940d5e

ErrorHandler decorator

The documentation mentions using the @ErrorHandler() decorator, but that decorator doesn't exist.

Please support @Authorized

No an issue , rather feature request:

It would be really nice if you could add some kind of @authenticated() decorator to controller and actions that will call some midleware to decide if user is authorized to call the controller action.

Thanks.

Cannot get any data into any Post method

I have a very simple controller method

@Post("/register") register(@Req() request: any, @Res() response: any) { console.log(JSON.stringify(request.body)); return ""; }

and I'm trying to pass in some post data using the curl CLI iunder windows:

curl -X POST -H "Content-Type: application/json" -d "{ \"email\": \"[email protected]\", \"name\": \"john\", \"password\": \"1\" }" localhost:8080/api/auth/register

Somehow I cannot for the life of me get any of the data to come through i.e. the body is a l w a y s empty.
I have absolutely no idea where the problem is as the @get methods work no problem.

Please advise.
Thansk you so much.

Routes from Directory not working

Hi,

When running the following two classes the Controller does not register. The server starts up and I can receive requests but I am unable to access my routes.

server.ts

/// <reference path='../typings/index.d.ts' />
import 'reflect-metadata';
import 'es6-shim';
import * as express from 'express';
import {useExpressServer} from 'routing-controllers';
import {createConnection, ConnectionOptions} from 'typeorm';
let bodyParser = require('body-parser');
let cookieParser = require('cookie-parser');
import session = require('express-session');

/**
 * The server.
 *
 * @class Server
 */
class Server {

    app: express.Application;

    /**
     * Bootstrap the application.
     *
     * @class Server
     * @method bootstrap
     * @static
     */
    public static bootstrap(): Server {
        return new Server();
    }

    /**
     * Constructor.
     *
     * @class Server
     * @constructor
     */
    constructor() {
        this.app = express();
        this.createServer(this.app);
    }

    /**
     * Configure application
     *
     * @class Server
     * @method config
     * @return void
     */
    private createServer(app: express.Application): void {
        /**************************************
         * set up the server
         **************************************/
        // base directory. we use it because file in "required" in another module
        const baseDir = __dirname;
        useExpressServer(app, {
            controllerDirs: [baseDir + "/server/controllers"],
            // controllerDirs: [baseDir + "/server/controllers/**/*.js"],
            // controllerDirs: [baseDir + "/server/controllers/**/*.controller.js"]
        });
        app.listen(process.env.PORT || 4200, function () {
            console.log('&&&&&&& Listening on 4200 &&&&&&');
        });
    }
}

let server = Server.bootstrap();
module.exports = server.app;

This compiles OK and prints out

&&&&&&& Listening on 4200 &&&&&&

test.controller.ts

import {Response, Request, Router} from 'express';
import {Controller, Get, Req, Res, Post} from 'routing-controllers';

@Controller()
export class TestController {

    constructor() {
        console.log("@@@@@@@@@@@@@@@@@@ TestController @@@@@@@@@@@@@@@@@@")
    }

    @Get('/')
    entry(@Req() request: Request, @Res() response: Response) {
        console.log("*************** entry()")

    }
}

Next, if I add require("./server/contollers/test.controller"); to the top of my server.ts the compiled code generates the following:

__decorate([
        routing_controllers_1.Get('/'),
        __param(0, routing_controllers_1.Req()),
        __param(1, routing_controllers_1.Res()), 
        __metadata('design:type', Function), 
        __metadata('design:paramtypes', [express_1.Request, express_1.Response]), 
        __metadata('design:returntype', void 0)

This code gives:

/Users/ts/Documents/workspace/testapp/src/server/contollers/test.controller.js:207
        __metadata('design:paramtypes', [express_1.Request, express_1.Response]), 
                                         ^

ReferenceError: express_1 is not defined
    at /Users/jt/Documents/workspace/testapp/src/server/contollers/test.controller.js:207:42
    at Object.<anonymous> (/Users/jt/Documents/workspace/testapp/src/server/contollers/test.controller.js:319:2)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.require (module.js:483:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/jt/Documents/workspace/testapp/src/server.js:12:1)

tsconfig.json

{
  "compilerOptions": {
    "lib": ["es5", "es6", "dom"],
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true,
    "pretty": true,
    "suppressImplicitAnyIndexErrors": true,
    "typeRoots": [
      "node_modules/@types"
    ],
    "types": [
      "typed-graphql"
    ]
  },
  "files": [
    "./src/server.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

It largely follows the examples so I am stuck as to why it doesn't work. Is this an issue?

Cheers

JT

Error with `@Res` decorator

When I try to run the following file:

import {Request, Response} from 'express';
import {Controller, Req, Res, Get} from 'routing-controllers';

@Controller()
class WelcomeController {

    @Get('/')
    index(@Req() request: Request, @Res() response: Response) {
        response.send('Hello world!');
    }

}

export default WelcomeController;

I get the following error:

$ node build/index.js
/Users/lorefnon/Workspace/server/node_modules/routing-controllers/decorator/params.js:30
        var reflectedType = Reflect.getMetadata("design:paramtypes", object, methodName)[index];
                                                                                        ^

TypeError: Cannot read property '1' of undefined
    at /Users/lorefnon/Workspace/server/node_modules/routing-controllers/decorator/params.js:30:89
    at /Users/lorefnon/Workspace/server/build/controllers/WelcomeController.js:9:37
    at DecorateProperty (/Users/lorefnon/Workspace/server/node_modules/reflect-metadata/Reflect.js:533:29)
    at Object.decorate (/Users/lorefnon/Workspace/server/node_modules/reflect-metadata/Reflect.js:98:20)
    at __decorate (/Users/lorefnon/Workspace/server/build/controllers/WelcomeController.js:4:92)
    at Object.<anonymous> (/Users/lorefnon/Workspace/server/build/controllers/WelcomeController.js:20:1)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)

The following however works as expected:

@Controller()
class WelcomeController {

    @Get('/')
    index() {
        return 'Hello world';
    }

}

Other relevant files:

index.ts:

import 'reflect-metadata';
import { createExpressServer } from 'routing-controllers';
import WelcomeController from './controllers/WelcomeController';

createExpressServer({
    controllers: [`${__dirname}/controllers/*`]
}).listen(9000);

tsconfig.json:

{
    "compilerOptions": {
	      "target": "es5",
	      "outDir": "dist",
	      "module": "commonjs",
	      "declaration": true,
	      "noImplicitAny": true,
	      "strictNullChecks": true,
	      "removeComments": true,
	      "moduleResolution": "node",
	      "sourceMap": true,
	      "inlineSources": true,
        "experimentalDecorators": true
    },
    "include": [
	      "src/**/*"
    ],
    "exclude": [
	      "node_modules",
	      "**/*.spec.ts"
    ]
}

Versions:

Including *.ts files in util.DirectoryExportedClassesLoader.importClassesFromDirectories() breaks import

Hi,

util.DirectoryExportedClassesLoader.importClassesFromDirectories() includes *ts files. This causes a problem when *.ts files are compiled to *.js files in the same directory. The importClassesFromDirectories() function does not know which file to use so it ignores.

Changing formats = [".js", ".ts"] to formats = [".js"] fixes any issues so may be an idea to slightly refactor this.

Cheers

JT

Can I extends controller class?

I want to put same common code into abstract controller like a template. And a concrete controller can extend a abstract controller.

I don't want to copy codes, is there a way to avoid that?

Server Caching

Is it possible to cache action results on the server side?

In ASP Web API it can be achieved the way below (though through external lib):
[CacheOutput(ClientTimeSpan = 100, ServerTimeSpan = 100)] public string Get() { return "s"; }

always return before getting the result.

Hi,
I am trying to fetch users from db using mongoose. But while making a GET request(http://localhost:3000/api/users) the call not wait until the callback comes from db. My code look likes below,

@JsonController("/api/users")
    export class UserController {    
    @Inject() private userService: UserService;

    @Get("/")
    @JsonResponse()
    getAll(@BodyParam("name") userName: string, @Req() request: Request, @Res() response: Response){
        this.userService.fetchAll((err, res) => {
            response.send(res);
        });
    }
}

How to fix this issue. I have tried fibers but its not working for me.

ParameterRequiredError is not working

when the required key is true on a @BodyParam the error is sent as clear text (ie: not put in double quotes) and the http code is not set correctly so it becomes 500 even if that's not a server error

middleware cant not handle exception

built by Ts2.1 ;
Expception throw in use function of middleware cant be handled correctly, this.handleError was undefined. 'this' scope is not work when call this.handleError.
Generated Code in ExpressDriver.js
ExpressDriver.prototype.registerMiddleware = function (middleware) {
if (!middleware.instance.use)
return;
this.express.use(function (request, response, next) {
var _this = this;
}
actually , I modified the js, the code can work.
ExpressDriver.prototype.registerMiddleware = function (middleware) {
if (!middleware.instance.use)
return;
var _this = this;
this.express.use(function (request, response, next) {

   }

Session Method Parameter Decorator

Is the @Session decorator avaible?
I attach to req.session an user object after sucessfull authentication and use it in controler method to check if user is an owner of demanded object from database.
It would be nice to have :

@Get("/posts")
getAll(@Session("user") user: User) {
   return postsRepository.getAllByUser(user);
}

And don't have to parse request object by myself 😉

Provide an example how to write unit tests.

Hello, first I want to say "thank you" for your library! Very useful.
Could you please provide an example, how to write unit / functional test for an application, written with you library?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.