Git Product home page Git Product logo

typescript-rest's Introduction

npm version Master Workflow Coverage Status Known Vulnerabilities BCH compliance

REST Services for Typescript

This is a lightweight annotation-based expressjs extension for typescript.

It can be used to define your APIs using decorators.

Table of Contents

Installation

This library only works with typescript. Ensure it is installed:

npm install typescript -g

To install typescript-rest:

npm install typescript-rest --save

Configuration

Typescript-rest requires the following TypeScript compilation options in your tsconfig.json file:

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "target": "es6" // or anything newer like esnext
  }
}

Basic Usage

import * as express from "express";
import {Server, Path, GET, PathParam} from "typescript-rest";

@Path("/hello")
class HelloService {
  @Path(":name")
  @GET
  sayHello( @PathParam('name') name: string ): string {
    return "Hello " + name;
  }
}

let app: express.Application = express();
Server.buildServices(app);

app.listen(3000, function() {
  console.log('Rest Server listening on port 3000!');
});

That's it. You can just call now:

GET http://localhost:3000/hello/joe

Using with an IoC Container

Install the IoC container and the serviceFactory for the IoC Container

npm install typescript-rest --save
npm install typescript-ioc --save
npm install typescript-rest-ioc --save

Then add a rest.config file in the root of your project:

{
  "serviceFactory": "typescript-rest-ioc"
}

And you can use Injections, Request scopes and all the features of the IoC Container. It is possible to use it with any other IoC Container, like Inversify.

Example:

class HelloService {
  sayHello(name: string) {
    return "Hello " + name;
  }
}

@Path("/hello")
class HelloRestService {
  @Inject
  private helloService: HelloService;

  @Path(":name")
  @GET
  sayHello( @PathParam('name') name: string): string {
    return this.sayHello(name);
  }
}

Complete Guide

Check our documentation.

Boilerplate Project

You can check this project to get started.

typescript-rest's People

Contributors

abhisekp avatar bleshik avatar d0whc3r avatar dr-bonez avatar iojichervo avatar jairelton avatar kazzkiq avatar mhenr18 avatar mr-short avatar msieurtoph avatar ngraef avatar qwerios avatar ruslan-sh-r avatar singular1ty94 avatar snyk-bot avatar tambry avatar thiagobustamante avatar ttopalov avatar vellengs 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

typescript-rest's Issues

typescript-rest has no exported member Preprocessor

I've been try to write a custom decorator using typescript-rest Preprocessor, which is working as expected if I run it in my local.

Here's my code for custom decorator.

import { Preprocessor } from "typescript-rest";
import { ForbiddenError } from "typescript-rest/dist/server-errors";
import { logger } from "../middleware/logger-mw";

const secured = (...args: any[]) =>
    async (req: any) => {
        if (args && args.length > 0) {
            let isPermitted: boolean = false;
            logger.info("Verifying The Roles :: " + JSON.stringify(args));
            for (const incRole of args) {
                for (const authObj of req.headers.currentUser.authorities) {
                    if (incRole === authObj.authority) {
                        isPermitted = true;
                        break;
                    }
                }
                if (isPermitted) {
                    break;
                }
            }
            if (isPermitted) {
                logger.info("Roles Permitted To Aceess API :: " + JSON.stringify(args));
            } else {
                logger.error("Acess Forbiden For Roles :: " + JSON.stringify(args));
                throw new ForbiddenError("Access Forbidden For Roles :: " + JSON.stringify(args));
            }
        }
        return req;
    };

export const Permission = (...args: any[]) => Preprocessor(secured.apply(null, args));

But as soon as I try run my node application inside docker it gives me below error.

> [email protected] start /usr/src/app
> ts-node src/app.ts


/usr/src/app/node_modules/ts-node/src/index.ts:296
        throw new TSError(formatDiagnostics(diagnosticList, cwd, ts, lineOffset))
              ^
TSError: โจฏ Unable to compile TypeScript
src/decorators/Permission.ts (1,10): Module '"/usr/src/app/node_modules/typescript-rest/dist/typescript-rest"' has no exported member 'Preprocessor'. (2305)
    at getOutput (/usr/src/app/node_modules/ts-node/src/index.ts:296:15)
    at /usr/src/app/node_modules/ts-node/src/index.ts:325:16
    at Object.compile (/usr/src/app/node_modules/ts-node/src/index.ts:479:11)
    at Module.m._compile (/usr/src/app/node_modules/ts-node/src/index.ts:379:43)
    at Module._extensions..js (module.js:663:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/usr/src/app/node_modules/ts-node/src/index.ts:382:12)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/usr/src/app/src/controllers/UtilityController.ts:4:1)
    at Module._compile (module.js:652:30)
    at Module.m._compile (/usr/src/app/node_modules/ts-node/src/index.ts:379:23)
    at Module._extensions..js (module.js:663:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/usr/src/app/node_modules/ts-node/src/index.ts:382:12)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/usr/src/app/src/controllers/index.ts:4:1)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `ts-node src/app.ts`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2018-08-27T16_39_15_515Z-debug.log

Below is my Dockerfile

# Taking Ubuntu As A Base OS
FROM ubuntu:16.04

#Creating a working directory
WORKDIR /usr/src/app

# Updating the apt repo
RUN rm -rf /var/lib/apt/lists/*
RUN apt-get update

# Installing curl
RUN apt-get install -y curl

#Installing Libfontconfig
RUN apt-get install -y libfontconfig

# Installing nodejs
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
RUN apt-get install -y nodejs

# Setting environment profile variable
# ENV profile prod

# copying the package.json and pakcage-lock.json
COPY package*.json ./
 
RUN apt-get install -y bzip2

# installing modules and their dependency
RUN npm install

# Bundle app source
COPY . .

EXPOSE 3004

CMD ["npm", "start"]

typescript-rest version in package.json

"typescript-rest": "^1.1.1",

Local Environment Node Version

v8.10.0

Add a Preprocessor decorator for controller class

It'd be really useful to have a middleware decorator that applies to all the sub-routes of a controller class like so:

@Preprocessor(logger)
@Path('/cars')
class Cars {
  ...
}

Here, logger applies to all the routes declared inside this class.

How to use loadServices ?

I used and adapted the code that I found in the README.md :

In /xx/yy/api-server.class :

const app = express();
const api = express.Router();
Server.loadServices(api, '../../api/*');
this.api.use('api', api);

In /api/*, I have all my decorated services, such as :

@Path('/someResources')
export class SomeResources { ... }

I expected that http://localhost:3000/api/someResources would serve me the service SomeResources, but it does not. It seems that it did not load anything at start ...

Can you help me using this ?

Note that when I import the service and use Server.buildServices(), the url http://localhost:3000/someResources works perfectly !

Services are not working when they have a constructor with an @Inject annotation

This will not work:

@Path('users')
@AutoWired
export class UsersRest extends BasicEndpoint<UserData>
{
    constructor(@Inject protected service: UsersService)
    {
        super(service);
    }
...

Perhaps the problem is in the InternalServer.buildServices method, when it tries to invoke the validateTargetType method. This is comparing a ioc_wrapper with a real target class and it's failling because they definitely are not equal.

Client implementation ?

Hi,

Is there a support for client implementation ?
I would like to be able to declare an interface, annotated for the declaration of the REST API and then :

  • Implement it on server side
  • Instantiate a client, on client side, in order to be able to call it like a function, without caring about REST at all.

Also it would be really great for Isomorphic apps, as it would enable to call the same api functions on server and client.

How to use express middleware with typescript-rest

I'd like to have a middleware, like authorization middleware for example.
How can I use middleware with typescript-rest.

Suppose I have something like this:

app = express();
const myMiddleware = (req, res, next) => {
  console.log("I'm in the middle");
  next();
}

@Path("/get")
class MyGetController {
  @GET
  getSomething() {
    return "Some response";
  }
}

app.use('/api', myMiddleware, MyGetController);

How can I do it? How can I augment a class with some middleware in front of it?
How can I use typescript-rest to write middleware, and to compose middleware with controllers?

How to throw HttpExceptions at runtime if a parameter (e.g. PathParam, BodyParam) has wrong type

Little example

@Path('/hello')
class HelloService {
    @Path(':name')
    @GET
    sayHello(@PathParam('name') name: number): string {        
        return `Hello ${name}`;
    }
}

How could I check the parameters if the type is wrong (in the example above, name is number) or a required param is missing and throw e.g. bad request. Any hint, how could I implement that nicely? :)

Further, I would use that information within Swagger/OpenAPI.

npm ignore generated folders

Could you add .nyc_output, reports and node_modules in ".npmignore"?, now when you download the package all these folders are included
Now, downloaded size is: 1.3MB
Excluding that folders size will be: ~556KB (also excluding "src" folder, size will be ~460KB)

Unable to resolve signature of method decorator when called as an expression

Executing task: tsc -p "/Users/x x x x x/workspace/example/ts-rest/tsconfig.json" <

index.ts(7,3): error TS1241: Unable to resolve signature of method decorator when called as an expression.
The terminal process terminated with exit code: 2

use code from basic example

import * as express from "express";
import {Server, Path, GET, PathParam} from "typescript-rest";

@path("/hello")
class HelloService {
@path(":name")
@get
sayHello( @PathParam('name') name: string): string {
return "Hello " + name;
}
}

let app: express.Application = express();
Server.buildServices(app);

app.listen(3000, function() {
console.log('Rest Server listening on port 3000!');
});

Incompatible with ES6 target

Summary:
When using the ES6 as TypeScript target, the compilation will fail.

Example:

import * as rest from "typescript-rest";

Compiler error:

node_modules/@types/es6-promise/index.d.ts(11,15): error TS2300: Duplicate identifier 'Promise'.
node_modules/@types/es6-promise/index.d.ts(42,19): error TS2300: Duplicate identifier 'Promise'.
node_modules/typescript/lib/lib.es6.d.ts(4852,11): error TS2300: Duplicate identifier 'Promise'.
node_modules/typescript/lib/lib.es6.d.ts(5175,11): error TS2300: Duplicate identifier 'Promise'.
node_modules/typescript/lib/lib.es6.d.ts(5342,13): error TS2300: Duplicate identifier 'Promise'.
node_modules/typescript/lib/lib.es6.d.ts(5560,11): error TS2300: Duplicate identifier 'Promise'.

Workaround:
Switch to ES5.

Fix:
Don't include the @types/es6-promise.

typescript-rest-jwt

I love using typescript-rest, but wanted to easily be able to secure my routes with JWT tokens so I whipped this up and finally got around to rolling it into a package.

It would be nice if you could add a "Supporting Libraries" or "Useful Tools" section to the already awesome README so others who run into my situation don't have to develop their own.

You can find it at https://www.npmjs.com/package/typescript-rest-jwt

~Jacob

Bootstrap project

Hi! Awesome project. Thank you very much for your work

I tried to find boilerplate, but didn't find any. So i made it by myself
But i need help to stabilize and standardize this boilerplate project
typescript-rest-boilerplate

So for now i have some questions:

  1. in ApiServer class i have some initialization code for controllers(handlers). But it's very annoying to add new class reference here each time i add new controller class

How can i avoid that and write like "hey take all classes from 'controller' folder and use them as handlers"?
Maybe you have some configuration var or class for such type of behavior?

  1. What files i missed? Maybe tslint.json, .editorconfig, etc.

More questions coming soon....

Multer improperly imported

Trying to compile the following:

import * as rest from "typescript-rest";

Will result in:

node_modules/typescript-rest/release/lib/server.d.ts(10,71): error TS2305: Module 'Express' has no exported member 'Multer'.

This looks like a bug in the typings not properly importing Multer. Any ideas?

Documentation how to modify headers

I'm adding this framework to the TechEmpower Framework Benchmarks and I need to add a required header--not a header param. Aside from setting these headers at the app level (where app is a typeof express.Application), how can I go about setting these headers at the route level? Say, I have the /plaintext route that should have a Content-Type of text/plain. How can I set this at the route level?

Always receiving an empty request body

I have the following endpoint:

@Path('/migrate')
@POST
async migrate (req: MigrationMigrateRequest): Promise<MigrationMigrateResponse> {

and no matter what data i send in the request body, req contains an empty object.
I have searched through all of the documentation and I can't determine why this is.

Publish Library

Hi,
please publish the library on npm with passport implementation.

Thanks

Unknown authentication strategy "jwt"

I am using:

Server.passportAuth("jwt", "roles"); and it says

Unknown authentication strategy "jwt".

passport.ts

import {ExtractJwt, Strategy, StrategyOptions} from "passport-jwt";

import {JwtUser, JwtUserPayload} from "../middlewares/jwtAuth";
const JWT_SECRET: string = "some-jwt-secret";
const jwtConfig: StrategyOptions = {
    jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme("JWT"),
    secretOrKey: Buffer.from(JWT_SECRET, "base64"),
};
module.exports = function (passport: any) {
    console.log("init jwt auth...");

    passport.use("jwt", new Strategy(jwtConfig, (payload: JwtUserPayload, done: (a: null, b: JwtUser) => void) => {
        const user: JwtUser = {
            id: payload.id,
            roles: payload.role.split(","),
        };
        done(null, user);
    }));

    passport.serializeUser((user: JwtUser, done: (a: null, b: string) => void) => {
        done(null, JSON.stringify(user));
    });

    passport.deserializeUser((user: string, done: (a: null, b: JwtUser) => void) => {
        done(null, JSON.parse(user));
    });
    passport.authenticate("jwt")
    console.log("init jwt done");
};

const passport = require ("passport");
require("./config/passport")(passport);

And of course: this.app.use(passport.initialize());

File upload with @FileParam('file') file: Express.Multer.File

I am testing the @FileParam('file') file: Express.Multer.File parameter.
I initially set up the server to use multer:

        const storage = multer.diskStorage({
            destination: function (req, file, cb) {
                cb(null, __dirname + '/resources/');
            },
            filename: function (req, file, cb) {
                cb(null, file.originalname + '-' + Date.now());
            }
        });

        this.app.use(multer({storage: storage, dest: __dirname + '/resources/'}).any());

then I use the parmeter in my controller:

        public async uploadFike(@FileParam('file') file: Express.Multer.File): Promise<IFileCreation> {
       Logger.debug(file) // file is always empty
        }

Can I address the file variable after it was uploaded? for me file is empty. I am new to multer so i don't know if I am missing something...

Authentication for certain routes?

How would you implement authentication on certain routes?
I'm new to typescript an decorators, is there an example or some kind of best practice for this task?

support register services through glob expressions.

Create a support to register services automatically, avoiding the annoying task to register each service, as previously describe in #21, or in #9.

The approach would be:

  Server.loadServices(app, 'lib/controllers/*');

or

  Server.loadServices(app, ['lib/controllers/*', '!**/exclude*']); 
  // includes all controllers, excluding that one which name starts with 'exclude'

or

  Server.loadServices(app, 'controllers/*', `${__dirname}/..`]); 
  // Inform a folder as origin for the patterns

Overloading of annotated inherited methods seem not to work for PUT

Hi there,
I managed to create a base REST endpoint defined using your library and it worked like a charm. Now I'm inheriting from this base service and try to overload the @get and the @put methods for a specific endpoint that differs only in those methods.

It's working fine for the @get case but it's complaing on the @put where the setup is the same I guess. The error is:

Method is already annotated with @1. You can only map a method to one HTTP verb.

Here a sripped down version of my classes:

abstract BaseService:
`class BaseService {
@path(':id')
@get
public getEntity(@PathParam('id') id: string, @QueryParam('$expand') expand: string): Promise {
... some code
}

@path(':id')
@put
public updateEntity(@PathParam('id') id: string, entity: any): Promise {
... some code
}
}`

The class that extends the previous one:
`@Path('/admin/viewconfig')
export class ViewConfigService extends BaseService {
@path(':id')
@get
public getEntity(@PathParam('id') viewid: string): Promise {
... some coding here... this overloading is working!
}

@path(':id')
@put
public updateEntity(@PathParam('id') viewId: string, entity: any): Promise {
... some code - but this overloading is complaining
}
}`

Do you have any idea why it is working for GET but not for PUT???

Thx in advance...

POST object with a property of Date type

Hello, first off, great library!

One issue I am having is, when I POST an object of a certain type, the properties of type "Date" are not deserialized into a Date object, they remain a string.

Example:

@POST
postInputDataSet( @PathParam("jobId") jobId: number, paramSet: InputDataSetEntity):Promise<InputDataSetEntity>
{
console.log(paramSet.beginDate.getDate());
}

this code fails because beginDate is not a Date, but String. Would automatic deserialization of a Date be possible through this library?

Making it work with 'async-listener'

Hey,
I'm using this https://github.com/othiym23/node-continuation-local-storage as a replacement for deprecated nodejs domain package for passing request context through all callbacks and promises.
In turn, this lib uses 'async-listener', which performs some instrumentation on global.Promise:
https://github.com/othiym23/async-listener/blob/master/index.js#L457
which is a problem, because of the way typescript-rest checks response:
https://github.com/thiagobustamante/typescript-rest/blob/master/src/server-container.ts#L343

I can send you a PR fixing this particular problem by adding "wrappedPromise" to the check, but I feel like there should be a better way of fixing this. Let me know if you want me to create the PR anyway.

Possible bug on path name and method name?

I have two services in different files:

src/controllers/v1/test.controller.ts
src/controllers/v2/test.controller.ts

The main path in the services are:

The first one

@path('test/hello/v1')
export class TestController {
@path('')
@post
public async testName(name: string): Promise {
console.log("hello" + name);
return;
}
}

The second one

@path('test/hello/v2')
export class TestController {
@path('')
@post
public async testName(name: string): Promise {
console.log("hello" + name);
return;
}
}

It throws me this error:

node_modules\typescript-rest\dist\decorators.js:1138
throw Error('Can not use more than one body parameter on the same method.');

I've tried many options but the only way to fix it is to do this:

The first one

@path('test/hello')
export class TestController {
@path('v1')
@post
public async testNameV1(name: string): Promise {
console.log("hello" + name);
return;
}
}

The second one

@path('test/hello')
export class TestController {
@path('v2')
@post
public async testNameV2(name: string): Promise {
console.log("hello" + name);
return;
}
}

Must put the end path in the method path name and change the method name. Is it good? Another way to do something like the first option?

Thank you.

Not able to get Server.swagger(...) to expose /api-docs endpoint

I was able to get swaggerGen to work, as well as normal routes using the @path decorator. However, I'm not able to expose the swagger endpoint using the example in the readme. Wondering if you could tell me what I'm doing wrong? Here is my server setup:

// server.ts
let expressApp: express.Express = express()
middleware.mountMiddleware(expressApp)
Routes.mountRoutes(expressApp, port)

let server = http.createServer(expressApp)
let io = require('socket.io')(server)
sockets.registerSockets(io)

server.listen(port, '0.0.0.0', function () {
	console.log('Express started on port ' + port)
})
// middleware.ts
export function mountMiddleware (expressApp) {
	// expressApp.use(morgan('combined'))
	wlog.log('debug', 'serving from static path ' + serverConfig.publicPath)
	expressApp.use('/', express.static(serverConfig.publicPath))
	expressApp.use(BodyParser.json())
	expressApp.use(cors())
}
// routes.ts
export function mountRoutes (app, port) {
	Server.buildServices(app)
	wlog.log('debug', 'setting up Server.swagger from cwd: ' + process.cwd())
	Server.swagger(app, './swagger/api/swagger/swagger.yaml', '/api-docs', '0.0.0.0:5674', ['http'])
}

GET to http://localhost:5674/api-docs results in ERR_CONNECTION_REFUSED
GET to http://localhost:3000/api-docs (just in case the route was exposed on the same port as the other routes) results in a status 404

Inject dependencies in router

Hi,
First of all, great work!
Is there a way I can inject dependencies into my router (like a repository service for instance)?
More generally can I have instance variable initialized in some way?

Manuel

error TS2300: Duplicate identifier 'X'.

node_modules/@types/express-serve-static-core/index.d.ts(32,10): error TS2300: Duplicate identifier 'PathParams'.
node_modules/@types/express-serve-static-core/index.d.ts(34,10): error TS2300: Duplicate identifier 'RequestHandlerParams'.

Deploy on Heroku

Hi guys!

Has anyone ever run a deploy on Heroku?

The build works correctly, but when trying to access the API there is some error that breaks the application.

Rest with pattern template

How can I do the following, I have a base class template

class BaseService {
    model=any;
    constructor(model){
        this.model=model;
    }

    async findAll(body){
        return await this.model.find(body);
    }
    async create(body){
        return await this.model.insert(body);
    }
}

and a child class

class UserService extends BaseService{
    constructor(model){
        super(model);
    }
}
class BookService extends BaseService{ 
    constructor(model){
        super(model);
    }
}

How can I generate the documentation of both using the template design template?

in this way if you can, but code is duplicated.

@Path("/users")

class UserService{
   @GET
   findAll(): Promise<Array<User>> {
      //...
   }
 @POST
  create():Promide<User>{}
}
@Path("/books")
class UserService {
   @GET
   findAll(): Promise<Array<User>> {
      //...
   }
 @POST
  create():Promide<User>{}
}

Error response in JSON format

UC: Implementing an async request.

  • while processing the request, an error condition occurs and it is necessary to inform client about the problem (preferably JSON)
  • when an error occurs in the service, there are 2 cases:
  1. rejecting the returned promise => content type is set to: text/html
  2. an exception is thrown => again, content type is set to: text/html

Desired behavior:

  • when an object is returned via reject(object), send back JSON (as for regular response)
  • when an exception is thrown, allow service to set content type and respond with JSON

Suggested workaround:
app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
if (err instanceof BadRequestError){
res.set("Content-Type", "application/json")
res.status(err.statusCode)
res.json({info : err.message, data: err.data});
} else {
next(err);
}
});

This works fine here:
@path("dummy1")
@get
dummy1(): Promise {
return new Promise(function (resolve, reject) {
throw new BadRequestError("Works fine, JSON is sent",{some:"data"});
});
}

But it does not work here:
@path("dummy2")
@get
dummy2(): Promise {
return new Promise(function (resolve, reject) {
setTimeout(()=>{
throw new BadRequestError("error handling not applied",{some:"data"});
},1000);
});
}

Doesn't play nice with Webpack

Dev version (non-webpacked) works great but when I build a Prod version w/ webpack I keep getting Error: Duplicated declaration for path [/users/cleaners/all], method [1].. There is only 1 path defined as such so unclear why this is the resulting error.

Stack:

/workdir/app/webpack:/node_modules/typescript-rest/dist/server-container.js:539
            throw Error("Duplicated declaration for path [" + resolvedPath + "], method [" + serviceMethod.httpMethod + "].");
^
Error: Duplicated declaration for path [/users/cleaners/all], method [1].
    at Function.Error [as resolvePath] (/workdir/app/webpack:/node_modules/typescript-rest/dist/server-container.js:539:1)
    at Function.resolvePath [as resolveProperties] (/workdir/app/webpack:/node_modules/typescript-rest/dist/server-container.js:521:1)
    at e.resolveProperties [as buildService] (/workdir/app/webpack:/node_modules/typescript-rest/dist/server-container.js:156:1)
    at buildService (/workdir/app/webpack:/node_modules/typescript-rest/dist/server-container.js:111:1)
    at Map.forEach (<anonymous>)
    at forEach (/workdir/app/webpack:/node_modules/typescript-rest/dist/server-container.js:109:1)
    at Map.forEach (<anonymous>)
    at e.forEach [as buildServices] (/workdir/app/webpack:/node_modules/typescript-rest/dist/server-container.js:107:1)
    at Function.buildServices (/workdir/app/webpack:/node_modules/typescript-rest/dist/server.js:24:1)
    at Object.buildServices (/workdir/app/webpack:/release/lib/index.js:32:1)
    at call (/workdir/app/webpack:/webpack/bootstrap:19:1)
    at __webpack_require__ (/workdir/app/webpack:/webpack/bootstrap:83:1)
    at Object.<anonymous> (/workdir/app/webpack:/webpack/bootstrap:83:1)
    at Module._compile (internal/modules/cjs/loader.js:654:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:695:10)
    at startup (internal/bootstrap/node.js:201:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:516:3)

QueryParam can not return a nullable number.

    @Path('query')
    @GET
    async getPaged(
        @QueryParam('keyword') keyword?: string,
        @QueryParam('primary_adviser') primary_adviser?: string,
        @QueryParam('secondary_advisers') secondary_advisers?: string,
        @QueryParam('intent') intent?: number,
        @QueryParam('status') status?: string,
        @QueryParam('type') type?: number,
        @QueryParam('page') page?: number,
        @QueryParam('size') size?: number,
        @QueryParam('sort') sort?: string): Promise<PaginateResponse<Customer[]>> {
           //  here size cannot be null ?

       }

I wanna page \ size can be nullable.

Is it possible to return hbs template to load landing page with rest API ?

I wanna use this api for all kind of request & response types and I want to render the 'index.hbs' template for the request made to path '/' like this :

@Path('/') export class IndexController { @GET public index(@ContextResponse response: express.Response) { response.render('index', {title: 'Social | Main Page'}); } }
Is it possible?

How to implement filters/middleware documentation

Could you please add some documentation on the read me file, on how one might implement some middle-ware or filters?
A good use-case is for someone looking to implement authentication and authorization.

Thanks

Incompatible with ES6 target

This does not seem to be related to #4.

The Basic example fails calling the route with the error:
TypeError: Class constructor HelloService cannot be invoked without 'new'

Target: ES6
Node: v6.9.5

Workaround: Switch to ES5 and include the @types/es6-promise.

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.