{"_id":"@d0whc3r/typescript-rest","_rev":"1-e95e8805db8a5ca2a2314ee9ee66f3a2","name":"@d0whc3r/typescript-rest","dist-tags":{"latest":"1.8.0"},"versions":{"1.8.0":{"name":"@d0whc3r/typescript-rest","version":"1.8.0","description":"A Library to create RESTFul APIs with Typescript","author":{"name":"Thiago da Rosa de Bustamante","email":"thiago@cruxframework.org"},"keywords":["API","REST","RESTFul","service","microservice","typescript","node server"],"main":"./dist/typescript-rest.js","typings":"./dist/typescript-rest.d.ts","license":"MIT","scripts":{"start":"tsc -w","build":"npm run clean && tsc","clean":"rimraf dist","lint":"tslint ./src/**/*.ts ./test/**/*.ts","format":"tsfmt -r","pretest":"cross-env NODE_ENV=test npm run build && npm run lint","test":"cross-env NODE_ENV=test mocha","test:coverage":"nyc npm test","tsc":"tsc","doc":"typedoc --out ./doc/ --name 'Typescript-rest' --readme ./README.MD --module commonjs --target ES5 --includeDeclarations --excludePrivate --excludeExternals ./src"},"nyc":{"include":["src/**/*.ts"],"extension":[".ts"],"require":["ts-node/register"],"reporter":["text-summary","html"],"sourceMap":true,"instrument":true},"dependencies":{"@types/body-parser":"1.17.0","@types/cookie-parser":"^1.4.1","@types/express":"^4.16.0","@types/express-serve-static-core":"^4.16.0","@types/multer":"1.3.7","@types/passport":"^0.4.6","@types/serve-static":"^1.13.2","body-parser":"^1.18.3","cookie-parser":"^1.4.3","cors":"^2.8.4","express":"^4.16.4","fs-extra":"^7.0.0","lodash":"^4.17.11","multer":"^1.4.1","passport":"^0.4.0","path":"^0.12.7","reflect-metadata":"^0.1.12","require-glob":"^3.2.0","swagger-ui-express":"^4.0.1","yamljs":"^0.3.0"},"devDependencies":{"@types/chai":"^4.1.6","@types/fs-extra":"5.0.4","@types/jsonwebtoken":"^7.2.8","@types/lodash":"^4.14.117","@types/mocha":"^5.2.5","@types/passport-jwt":"^3.0.1","@types/request":"^2.47.1","@types/yamljs":"^0.2.30","chai":"^4.2.0","coveralls":"^3.0.2","cross-env":"^5.2.0","istanbul":"^0.4.5","jsonwebtoken":"^8.3.0","mocha":"^5.2.0","nyc":"^13.0.1","passport-jwt":"^4.0.0","request":"^2.88.0","rimraf":"^2.6.2","source-map-support":"^0.5.9","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.13.0","typescript":"^3.1.3","typescript-formatter":"^7.2.2","typescript-ioc":"^1.2.4"},"repository":{"type":"git","url":"git+https://github.com/d0whc3r/typescript-rest.git"},"bugs":{"url":"https://github.com/d0whc3r/typescript-rest/issues"},"directories":{"lib":"dist","doc":"doc"},"engines":{"node":">=6.0.0"},"engineStrict":true,"gitHead":"c33510581454e039ed2a7c4d8e5d75c2d707f6c9","homepage":"https://github.com/d0whc3r/typescript-rest#readme","_id":"@d0whc3r/typescript-rest@1.8.0","_npmVersion":"6.4.1","_nodeVersion":"8.12.0","_npmUser":{"name":"d0whc3r","email":"d0whc3r@gmail.com"},"dist":{"integrity":"sha512-4tFBAQWo08liDYqi4qd7bA9QrHPClUxMYSVTlwQDbItQjAqzOMiamKki76GP2uxYkqMf7vCHbEYBYe8cNLiuLQ==","shasum":"4a7cb050955971e06ee15babbbfe5bc63f540398","tarball":"https://registry.npmjs.org/@d0whc3r/typescript-rest/-/typescript-rest-1.8.0.tgz","fileCount":86,"unpackedSize":1634860,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbwIO4CRA9TVsSAnZWagAAvW8P/RD++YpBMNUJo6htcsQb\njsBukE1c6cu+jmwERcuYIPMhKyVOg+Or1OYmm0a11/2MQez6x6343MBRjKQY\nVLinHunnlS8xI94ozvmAsYMIEnjRR2t6ChvpVAX15jdTBt/nh+feDzkLCAtz\ntjCirZvvyP7t9V8WpLudgG3NCM92aAZofEsibW2y1uqQLLkWgjDmbNtj/3Ld\nBFY/kZXiSphhsvqaBRdbcsMJ8oeqXHtibPfE88hgyUbblQVr7MzZFQrhy/Wq\nBFEXZrezYSd1D4DSbAaYY4hMwFTUQ5Gvkij8tJ1rB9qNbHE/q2qZ5Cm+gDg5\nPZCWnxPoIlXvGICjQD4HwBe08/GR5xd/SwhbmhPW61yOgUeJ4LbbN2hCcoX3\nIJNgyfs5Tn9QHMxiESp4vxjtFPcksimKSMVKyZLZKP14alBajQxyT4yin3w+\nSAGNRjA+eRmF14gzZv6juCNwkmO9DIzWmdzddAdWIqcWTMmYvHbUyaqa/T/m\nxwhOHE7ui3XGgwzSu4tDskcXTgd3jefrnIXrkIdW4meq8EDRVOHYUVfzE2rp\n/cvIfTdTMxyXZ+WrZfuFQ3DkvnKCCMvcVTT/DOXUUsAT0vFLJyY9aY2KORRN\nb9b3v7IWUq5YmU3EkgBhEHdJn/j8xmrO+SDzk7LgZ7r2aPlZinKeaCXnTyuC\nAcIb\r\n=8VH9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICJFajeo9MdRsl/RRgNpidrY+FzLBocR6rHy6209B589AiEAniJr0hFJ6BsIjFch/ZmwicGB0VctN05TlNXf9kUIjiA="}]},"maintainers":[{"name":"d0whc3r","email":"d0whc3r@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typescript-rest_1.8.0_1539343287224_0.05678130815241689"},"_hasShrinkwrap":false}},"time":{"created":"2018-10-12T11:21:27.059Z","1.8.0":"2018-10-12T11:21:27.439Z","modified":"2022-04-05T02:28:53.807Z"},"maintainers":[{"name":"d0whc3r","email":"d0whc3r@gmail.com"}],"description":"A Library to create RESTFul APIs with Typescript","homepage":"https://github.com/d0whc3r/typescript-rest#readme","keywords":["API","REST","RESTFul","service","microservice","typescript","node server"],"repository":{"type":"git","url":"git+https://github.com/d0whc3r/typescript-rest.git"},"author":{"name":"Thiago da Rosa de Bustamante","email":"thiago@cruxframework.org"},"bugs":{"url":"https://github.com/d0whc3r/typescript-rest/issues"},"license":"MIT","readme":"[![npm version](https://badge.fury.io/js/%40d0whc3r%2Ftypescript-rest.svg)](https://badge.fury.io/js/%40d0whc3r%2Ftypescript-rest)\n[![Build Status](https://travis-ci.org/d0whc3r/typescript-rest.svg?branch=master)](https://travis-ci.org/d0whc3r/typescript-rest)\n[![Coverage Status](https://coveralls.io/repos/github/d0whc3r/typescript-rest/badge.svg?branch=master)](https://coveralls.io/github/d0whc3r/typescript-rest?branch=master)\n[![Known Vulnerabilities](https://snyk.io/test/github/d0whc3r/typescript-rest/badge.svg?targetFile=package.json)](https://snyk.io/test/github/d0whc3r/typescript-rest?targetFile=package.json)\n\n# REST Services for Typescript\nThis is a lightweight annotation-based [expressjs](http://expressjs.com/) extension for typescript.\n\nIt can be used to define your APIs using ES7 decorators.\n\n**Project Sponsors**\n\nThis project is supported by [Leanty](https://github.com/Leanty/)'s team and is widely used by its main product: The [Tree Gateway](http://www.treegateway.org) API Gateway.\n\n**Table of Contents** \n\n- [REST Services for Typescript](#)\n  - [Installation](#installation)\n  - [Configuration](#configuration)\n  - [Basic Usage](#basic-usage)\n  - [Boilerplate Project](#boilerplate-project)  \n  - [Complete Guide](#complete-guide)\n    - [Server](#server)\n      - [Registering Services](#registering-services)\n    - [@Path Decorator](#path-decorator)\n      - [Path Parameters](#path-parameters)\n    - [@Security Decorator](#security-decorator)\n    - [Http Methods](#http-methods)\n    - [Parameters](#parameters)\n    - [Service Context](#service-context)\n    - [Service Return](#service-return)\n      - [Asynchronous services](#asynchronous-services)\n    - [Errors](#errors)\n    - [BodyParser Options](#bodyparser-options)\n    - [Types and languages](#types-and-languages)\n    - [IoC](#ioc)\n    - [Inheritance and abstract services](#inheritance-and-abstract-services)    \n    - [Preprocessors](#preprocessors)\n  - [Swagger](#swagger)\n - [Breaking Changes - 1.0.0](#breaking-changes)\n\n## Installation\n\nThis library only works with typescript. Ensure it is installed:\n\n```bash\nnpm install typescript -g\n```\n\nTo install typescript-rest:\n\n```bash\nnpm install typescript-rest --save\n```\n\n## Configuration\n\nTypescript-rest requires the following TypeScript compilation options in your tsconfig.json file:\n\n```typescript\n{\n  \"compilerOptions\": {\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  }\n}\n```\n\n## Basic Usage\n\n```typescript\nimport * as express from \"express\";\nimport {Server, Path, GET, PathParam} from \"typescript-rest\";\n\n@Path(\"/hello\")\nclass HelloService {\n  @Path(\":name\")\n  @GET\n  sayHello( @PathParam('name') name: string): string {\n    return \"Hello \" + name;\n  }\n}\n\nlet app: express.Application = express();\nServer.buildServices(app);\n\napp.listen(3000, function() {\n  console.log('Rest Server listening on port 3000!');\n});\n\n```\n\nThat's it. You can just call now:\n\n```\nGET http://localhost:3000/hello/joe\n```\n\n## Boilerplate Project\n\nYou can check [this project](https://github.com/vrudikov/typescript-rest-boilerplate) to get started.\n\n## Complete Guide\n\nThis library allows you to use ES7 decorators to configure your services using \nexpressjs. \n\n### Server\n\nThe Server class is used to configure the server, like: \n\n```typescript\nlet app: express.Application = express();\nServer.setFileDest('/uploads');\nServer.buildServices(app);\napp.listen(3000, function() {\n  console.log('Rest Server listening on port 3000!');\n});\n```\n\nNote that Server receives an ```express.Router``` instance. Then it configures\nall the routes based on the decorators used on your classes.\n\nSo, you can use also any other expressjs feature, like error handlers, middlewares etc \nwithout any restriction.  \n\n#### Registering Services\n\nWhen you call: \n\n```typescript\nServer.buildServices(app);\n```\n\nThe service will expose all services that can be found in the imported module into the express router provided. But it is possible to choose which services you want to expose.\n\n```typescript\nimport * as express from \"express\";\nimport {Server} from \"typescript-rest\";\nimport {ServiceOne} from \"./service-one\";\nimport {ServiceTwo} from \"./service-two\";\nimport {ServiceThree} from \"./service-three\";\n\nlet app: express.Application = express();\nServer.buildServices(app, ServiceOne, ServiceTwo, ServiceThree);\n```\n\nIt is possible to use multiples routers:\n\n\n```typescript\nServer.buildServices(adminRouter, ...adminApi);\nServer.buildServices(app, ServiceOne);\n```\n\nAnd it is, also, possible to use glob expressions to point where your services are:\n\n```typescript\nconst app = express();\n\nconst apis = express.Router();\nconst admin = express.Router();\n\nServer.loadServices(apis, 'lib/controllers/apis/*');\nServer.loadServices(admin, 'lib/controllers/admin/*');\n\napp.use('apis', apis);\napp.use('admin', admin);\n```\n\nThat will register all services exported by any file located under ```lib/controllers/apis``` in the ```apis``` router and services in ```lib/controllers/admin``` in the ```admin``` router.\n\nNegation is also supported in the glob patterns:\n\n```typescript\n  Server.loadServices(app, ['lib/controllers/*', '!**/exclude*']); \n  // includes all controllers, excluding that one which name starts with 'exclude'\n```\n\nAnd it is possilbe to inform a base folder for the patterns: \n\n```typescript\n  Server.loadServices(app, 'controllers/*', `${__dirname}/..`]); \n  // Inform a folder as origin for the patterns\n```\n\n### @Path Decorator\n\nThe @Path decorator allow us to define a router path for a given endpoint.\nRoute paths, in combination with a request method, define the endpoints at \nwhich requests can be made. Route paths can be strings, string patterns, or regular expressions.\n\nThe characters ?, +, *, and () are subsets of their regular expression counterparts. \nThe hyphen (-) and the dot (.) are interpreted literally by string-based paths.\n\n\n*We use [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the \nroute paths; see the path-to-regexp documentation for all the possibilities in defining route paths.*\n\n\nSome examples:\n\n```typescript\n@Path(\"/hello\")\nclass HelloService {\n}\n```\n\n```typescript\n@Path(\"/test/hello\")\nclass TestService {\n}\n```\n\nThis route path will match acd and abcd:\n\n```typescript\n@Path(\"ab?cd\")\nclass TestService {\n}\n```\n\nThis route path will match abcd, abbcd, abbbcd, and so on:\n\n```typescript\n@Path(\"ab+cd\")\nclass TestService {\n}\n```\n\nThis route path will match abcd, abxcd, abRANDOMcd, ab123cd, and so on:\n\n```typescript\n@Path(\"ab*cd\")\nclass TestService {\n}\n```\n\nThis route path will match /abe and /abcde:\n\n```typescript\n@Path(\"/ab(cd)?e\")\nclass TestService {\n}\n```\n\nThis route path will match butterfly and dragonfly, but not butterflyman, dragonfly man, and so on:\n\n```typescript\n@Path(\"/.*fly$/\")\nclass TestService {\n}\n```\n#### Path Parameters\n\nRoute parameters are named URL segments that are used to capture the values specified at their position in the URL. \nThe captured values are populated in the req.params object, with the name of the route parameter specified in \nthe path as their respective keys. They can be refered through @PathParam decorator on a service method argument.\n\nSome examples:\n\n```typescript\n@Path(\"/users\")\nclass UserService {\n   @Path(\"/:userId/books/:bookId\")\n   @GET\n   getUserBook(@PathParam(\"userId\") userId: number, @PathParam(\"bookId\") bookId: number): Promise<Book> {\n      //...\n   }\n}\n```\nThe requested URL http://localhost:3000/users/34/books/8989 would map the parameters as:\n\n```\n   userId: \"34\"\n   bookId: \"8989\"\n```\n\nSince the hyphen (-) and the dot (.) are interpreted literally, they can be used along with route \nparameters for useful purposes.\n\n```\nRoute path: /flights/:from-:to\nRequest URL: http://localhost:3000/flights/LAX-SFO\nreq.params: { \"from\": \"LAX\", \"to\": \"SFO\" }\n```\n\n```\nRoute path: /plantae/:genus.:species\nRequest URL: http://localhost:3000/plantae/Prunus.persica\nreq.params: { \"genus\": \"Prunus\", \"species\": \"persica\" }\n```\n\n### @Security Decorator\n\nThe @Security decorator allow us to define a authorization for a given endpoint.\nSecurity is using [passport](https://github.com/jaredhanson/passport) and it can be configured using\n`passportAuth` method in `Server`\n\n```typescript\nServer.passportAuth(strategy, roleKey);\n```\n\n- strategy: is part of passport configuration\n- roleKey: by default \"*roles*\", it is part of user object format\n\nSome examples:\n\n```typescript\n@Security()\nclass HelloService {\n    @Security(\"ROLE_ADMIN\")\n    admin() {}\n\n    authorized() {}\n}\n```\n\n```typescript\n@Security(\"ROLE_USER\")\nclass TestService {\n}\n```\n\n```typescript\n@Security([\"ROLE_ADMIN\", \"ROLE_USER\"])\nclass AuthService {\n}\n```\n\n### Http Methods\n\nWe have decorators for each HTTP method. Theses decorators are used on service methods already bound\nto a Path route to specify the endpoint at which requests can be made.\n\nThe following decorators can be used:\n\n  - @GET \n  - @POST\n  - @PUT\n  - @PATCH\n  - @DELETE\n  - @OPTIONS\n  - @HEAD\n\nAlso exists mapping options to use @Path and @Method together:\n\n  - @GETMapping \n  - @POSTMapping\n  - @PUTMapping\n  - @PATCHMapping\n  - @DELETEMapping\n  - @OPTIONSMapping\n  - @HEADMapping\n\nSome examples:\n\n```typescript\n@Path(\"/users\")\nclass UserService {\n   @GET\n   getUsers(): Promise<Array<User>> {\n      //...\n   }\n\n   @GET\n   @Path(\":userId\")\n   getUser(@PathParam(\"userId\")): Promise<User> {\n      //...\n   }\n\n   @PUT\n   @Path(\":userId\")\n   saveUser(@PathParam(\"userId\"), user: User): void {\n      //...\n   }\n}\n```\n\nUsing mappings:\n\n```typescript\n@Path(\"/users\")\nclass UserService {\n   @GET\n   getUsers(): Promise<Array<User>> {\n      //...\n   }\n\n   @GETMapping(\":userId\")\n   getUser(@PathParam(\"userId\")): Promise<User> {\n      //...\n   }\n\n   @PUTMapping(\":userId\")\n   saveUser(@PathParam(\"userId\"), user: User): void {\n      //...\n   }\n}\n```\n\nOnly methods decorated with one of this HTTP method decorators are exposed as handlers for \nrequests on the server.\n\nA single method can only be decorated with one of those decorators at a time.\n\n### Parameters\n\nThere are decorators to map parameters to arguments on service methods. Each decorator can map a\ndifferente kind of parameter on request.\n\nThe following decorators are available:\n\nDecorator | Description\n--------- | -----------\n@PathParam | Parameter in requested URL path \n@QueryParam | Parameter in the query string \n@FormParam | Parameter in an HTML form \n@HeaderParam | Parameter in the request header\n@CookieParam | Parameter in a cookie  \n@FileParam | A File in a multipart form  \n@FilesParam | An array of Files in a multipart form  \n@Param | Parameter in the query string or in an HTML form\n \nSome examples:\n\n```typescript\n@Path(\"/sample\")\nclass Sample {\n   @GET\n   test(@QueryParam(\"limit\") limit:number, @QueryParam(\"skip\") skip:number) {\n      //...\n      // GET http://domain/sample?limit=5&skip=10\n   }\n\n   @POST\n   test(@FormParam(\"name\") name:string) {\n      //...\n      // POST http://domain/sample\n      // body: name=joe\n   }\n\n   @POST\n   @Path(\"upload\")\n   testUploadFile( @FileParam(\"myFile\") file: Express.Multer.File, \n                   @FormParam(\"myField\") myField: string) {\n      //...\n      /* POST http://domain/sample/upload\n      Content-Type: multipart/form-data; boundary=AaB03x\n\n      --AaB03x\n      Content-Disposition: form-data; name=\"myField\"\n\n      Field Value\n      --AaB03x\n      Content-Disposition: form-data; name=\"myFile\"; filename=\"file1.txt\"\n      Content-Type: text/plain\n\n      ... contents of file1.txt ...\n      --AaB03x--\n      */\n   }\n}\n```\n\nAn argument that has no decorator is handled as a json serialized entity in the request body \n\n```typescript\n@Path(\"/sample\")\nclass Sample {\n   @POST\n   test(user: User) {\n      //...\n      // POST http://domain/sample\n      // body: a json representation of the User object\n   }\n}\n```\n\nThe ``` @*Param ``` decorators can also be used on service class properties.  \n\nAn example:\n\n```typescript\n @Path(\"users/:userId/photos\")\n class TestService {\n   @PathParam('userId')\n   userId: string;\n\n   @GET\n   getPhoto(@PathParam('photoId')) {\n      // Get the photo and return\n   }\n }\n```\n\n\n### Service Context\n\nA Context object is created to group informations about the current request being handled.\nThis Context can be accessed by service methods.\n\nThe Context is represented by the ``` ServiceContext ``` class and has the following properties:\n\nProperty | Type | Description\n-------- | ---- | -----------\nrequest | express.Request | The request object \nresponse | express.Response | The response object \nlanguage | string | The resolved language to be used to handle the current request.  \naccept | string | The preferred media type to be used to respond the current request. \nnext | express.NextFunction | The next function. It can be used to delegate to the next middleware registered the processing of the current request. \n\n\nSee [Types and languages](#types-and-languages) to know how the language and accept fields are calculated.\n\nThe ``` @Context ``` decorator can be used on service method's arguments or on service class properties to bind \nthe argument or the property to the current context object.  \n\nA Context usage example:\n\n```typescript\n @Path(\"context\")\n class TestService {\n   @Context\n   context: ServiceContext;\n\n   @GET\n   sayHello() {\n      switch (this.context.language) {\n         case \"en\":\n            return \"Hello\";\n         case \"pt\":\n            return \"Olá\";\n      }\n      return \"Hello\";\n   }\n }\n```\n\nWe can use the decorator on method arguments too:\n\n```typescript\n @Path(\"context\")\n class TestService {\n\n   @GET\n   sayHello(@Context context: ServiceContext) {\n      switch (context.language) {\n         case \"en\":\n            return \"Hello\";\n         case \"pt\":\n            return \"Olá\";\n      }\n      return \"Hello\";\n   }\n }\n```\n\nYou can use, also, one of the other decorators to access directly one of \nthe Context property. It is a kind of suggar syntax.\n\n  - @ContextRequest: To access ServiceContext.request\n  - @ContextResponse: To access ServiceContext.response\n  - @ContextNext: To access ServiceContext.next\n  - @ContextLanguage: To access ServiceContext.language\n  - @ContextAccept: To access ServiceContext.accept\n\n```typescript\n @Path(\"context\")\n class TestService {\n\n   @GET\n   sayHello(@ContextLanguage language: string) {\n      switch (language) {\n         case \"en\":\n            return \"Hello\";\n         case \"pt\":\n            return \"Olá\";\n      }\n      return \"Hello\";\n   }\n }\n```\n\n### Service Return\n\nThis library can receive the return of your service method and handle the serialization of the response as long as\nhandle the correct content type of your result and the response status codes to be sent.\n\nWhen a primitive type is returned by a service method, it is sent as a plain text into the response body.\n\n```typescript\n@GET\nsayHello(): string {\n  return \"Hello\";\n}\n```\n\nThe response will contains only the String ``` Hello ``` as a plain text \n\nWhen an object is returned, it is sent as a json serialized string into the response body.\n\n```typescript\n@GET\n@Path(\":id\")\ngetPerson(@PathParam(\":id\") id: number): Person {\n  return new Person(id);\n}\n```\n\nThe response will contains the person json serialization (ex: ``` {id: 123} ```. The response \nwill have a ```application/json``` context type. \n\nWhen the method returns nothing, an empty body is sent withh a ```204``` status code.\n\n```typescript\n@POST\ntest(myObject: MyClass): void {\n  //...\n}\n```\n\nWe provide also, some special types to inform that a reference to a resource is returned and \nthat the server should handle it properly.\n\nType | Description\n---- | -----------\nNewResource | Inform that a new resource was created. Server will add a Location header and set status to 201 \nRequestAccepted | Inform that the request was accepted but is not completed. A Location header should inform the location where the user can monitor his request processing status. Server will set the status to 202 \nMovedPermanently | Inform that the resource has permanently moved to a new location, and that future references should use a new URI with their requests. Server will set the status to 301 \nMovedTemporarily | Inform that the resource has temporarily moved to another location, but that future references should still use the original URI to access the resource. Server will set the status to 302 \n\n\n```typescript\nimport {Return} from \"typescript-rest\";\n\n@Path(\"test\")\nclass TestService {\n   @POST\n   test(myObject: MyClass, @ContextRequest request: express.Request): Return.NewResource<void> {\n      //...\n      return new Return.NewResource<void>(req.url + \"/\" + generatedId);\n   }\n\n   @POST\n   testWithBody(myObject: MyClass, @ContextRequest request: express.Request): Return.NewResource<string> {\n      //...\n      return new Return.NewResource<string>(req.url + \"/\" + generatedId, 'The body of the response');\n   }\n}\n```\n\nThe server will return an empty body with a ```201``` status code and a ```Location``` header pointing to \nthe URL of the created resource. \n\nIt is possible to specify a body to be sent in responses:\n\n```typescript\nimport {Return} from \"typescript-rest\";\n\ninterface NewObject {\n  id: string;\n}\n\n@Path(\"test\")\nclass TestService {\n   @POST\n   test(myObject: MyClass, @ContextRequest request: express.Request): Return.NewResource<NewObject> {\n      //...\n      return new Return.NewResource<NewObject>(req.url + \"/\" + generatedId, {id: generatedId}); //Returns a JSON on body {id: generatedId}\n   }\n}\n```\n\n\nYou can use special types to download files:\n\nType | Description\n---- | -----------\nDownloadResource | Used to reference a resource (by its fileName) and download it\nDownloadBinaryData | Used to return a file to download, based on a Buffer object\n\nFor example: \n\n```typescript\nimport {Return} from \"typescript-rest\";\n\n@Path(\"download\")\nclass TestDownload {\n  @GET\n  testDownloadFile(): Return.DownloadResource {\n    return new Return.DownloadResource(__dirname +'/test-rest.spec.js', '/test-rest.spec.js');\n  }\n\n  @GET\n  testDownloadFile(): Promise<Return.DownloadBinaryData> {\n    return new Promise<Return.DownloadBinaryData>((resolve, reject)=>{\n      fs.readFile(__dirname + '/test-rest.spec.js', (err, data)=>{\n        if (err) {\n          return reject(err);\n        }\n        return resolve(new Return.DownloadBinaryData(data, 'application/javascript', 'test-rest.spec.js'))\n      });\n    });\n  }\n}\n```\n\n\n#### Asynchronous services\n\nThe above section shows how the types returned are handled by the Server. However, most of the previous examples are working\nsynchronously. The recommended way is to work asynchronously, for a better performance.\n\nTo work asynchronously, you can return a ```Promise``` on your service method. The above rules to handle return types \napplies to the returned promise resolved value.\n\nSome examples:\n\n```typescript\nimport {Return} from \"typescript-rest\";\n\n@Path(\"async\")\nclass TestService {\n   @POST\n   test(myObject: MyClass, @ContextRequest request: express.Request): Promise<Return.NewResource> {\n      return new Promise<Return.NewResource>(function(resolve, reject){\n         //...\n         resolve(new Return.NewResource(req.url + \"/\" + generatedId));\n      });\n   }\n\n   @GET\n   testGet() {\n      return new Promise<MyClass>(function(resolve, reject){\n         //...\n         resolve(new MyClass());\n      });\n   }\n}\n```\n\nIt is important to observe that you can inform your return type explicitly or not, as you can see \nin the above example.  \n\nYou can also use ```async``` and ```await```:\n\n```typescript\n@Path('async')\nexport class MyAsyncService {\n    @GET\n    @Path('test')\n    async test( ) {\n        let result = await this.aPromiseMethod();\n        return result;\n    }\n\n    @GET\n    @Path('test2')\n    async test2( ) {\n        try {\n            let result = await this.aPromiseMethod();\n            return result;\n        } catch (e) {\n            // log error here, if you want\n            throw e;\n        }\n    }\n\n    private aPromiseMethod() {\n        return new Promise<string>((resolve, reject) => {\n            setTimeout(() => {\n                resolve('OK');\n            }, 10);\n        });\n    }\n}\n```\n\n### Errors\n\nThis library provide some Error classes to map the problems that you may want to report to your clients.\n\n\nType | Description\n---- | -----------\nBadRequestError | Used to report errors with status code 400. \nUnauthorizedError | Used to report errors with status code 401. \nForbiddenError | Used to report errors with status code 403. \nNotFoundError | Used to report errors with status code 404. \nMethodNotAllowedError | Used to report errors with status code 405. \nNotAcceptableError | Used to report errors with status code 406. \nConflictError | Used to report errors with status code 409. \nInternalServerError | Used to report errors with status code 500. \nNotImplementedError | Used to report errors with status code 501. \n\nIf you throw any of these errors on a service method, the server you log the \nproblem and send a response with the appropriate status code an the error message on its body.\n\n```typescript\nimport {Errors} from \"typescript-rest\";\n\n@Path(\"async\")\nclass TestService {\n   @GET\n   @Path(\"test1\")\n   testGet() {\n      return new Promise<MyClass>(function(resolve, reject){\n         //...\n      throw new Errors.NotImplementedError(\"This operation is not available yet\");\n      });\n   }\n\n   @GET\n   @Path(\"test2\")\n   testGet2() {\n      return new Promise<MyClass>(function(resolve, reject){\n         //...\n         reject(new Errors.NotImplementedError(\"This operation is not available yet\"));\n      });\n   }\n\n   @GET\n   @Path(\"test3\")\n   testGet3() {\n      throw new Errors.NotImplementedError(\"This operation is not available yet\");\n   }\n}\n```\n\nAll the three operations above will return a response with status code ```501``` and a message on the body\n```This operation is not available yet```\n\nIf you want to create a custom error that report your own status code, just extend the base class ```HttpError```.\n\n\n```typescript\nimport {HttpError} from \"typescript-rest\";\n\nclass MyOwnError extends HttpError {\n  static myNoSenseStatusCode: number = 999;\n  constructor(message?: string) {\n    super(\"MyOwnError\", MyOwnError.myNoSenseStatusCode, message);\n  }\n}\n```\n\nYou must remember that all uncaught errors are handled by a expressjs [error handler](http://expressjs.com/en/guide/error-handling.html#the-default-error-handler). You could want to customize it to allow you to inform how the errors will be delivered to your users. For more on this (for those who wants, for example, to send JSON errors), take a look at [this question](https://github.com/d0whc3r/typescript-rest/issues/16);\n\n### BodyParser Options\n\nIf you need to inform any options to the body parser, you can use the @BodyOptions decorator.\n\nYou can inform any property accepted by [bodyParser](https://www.npmjs.com/package/body-parser)\n\nFor example:\n```typescript\nimport {HttpError} from \"typescript-rest\";\n\nimport {Errors} from \"typescript-rest\";\n\n@Path(\"async\")\nclass TestService {\n   @POST\n   @Path(\"test1\")\n   @BodyOptions({limit:'100kb'})\n   testPost(myData) {\n      return new Promise<MyClass>(function(resolve, reject){\n         //...\n         throw new Errors.NotImplementedError(\"This operation is not available yet\");\n      });\n   }\n\n   @GET\n   @Path(\"test2\")\n   @BodyOptions({extended:false})\n   testPost2(@FormParam(\"field1\")myParam) {\n      return new Promise<MyClass>(function(resolve, reject){\n         //...\n         reject(new Errors.NotImplementedError(\"This operation is not available yet\"));\n      });\n   }\n\n   @GET\n   @Path(\"test3\")\n   testGet3() {\n      throw new Errors.NotImplementedError(\"This operation is not available yet\");\n   }\n}\n```\n\nIt can be used, for example, to inform the bodyParser that it must handle date types for you:\n\n```typescript\nfunction dateReviver(key, value) {\n    let a;\n    if (typeof value === 'string') {\n        a = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2}(?:\\.\\d*)?)Z$/.exec(value);\n        if (a) {\n            return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],\n                            +a[5], +a[6]));\n        }\n    }\n    return value;\n}\n\n@Path('test')\nclass MyRestService {\n   @POST\n   @BodyOptions({reviver: dateReviver})\n   myHandler(param) {\n      //...\n   }\n} \n```\n\n### Types and languages\n\nIt is possible to use decorators to inform the server which languages or mime types are supported by each service method.\n\nThese decorators can be used on the service class or on a service method (or both).\n\nThe following decorators are available:\n\nDecorator | Description\n--------- | -----------\nAcceptLanguage | Tell the [[Server]] that a class or a method should only accept requests from clients that accepts one of the supported languages. \nAccept | Tell the [[Server]] that a class or a method should only accept requests from clients that accepts one of the supported mime types. \n \nSee some examples:\n\n```typescript\n@Path(\"test\")\n@AcceptLanguage(\"en\", \"pt-BR\")\nclass TestAcceptService {\n  @GET\n  testLanguage(@ContextLanguage language: string): string {\n    if (language === 'en') {\n      return \"accepted\";\n    }\n    return \"aceito\";\n  }\n}\n```\n\nIn the above example, we declare that only ```English``` and ```Brazilian Portuguese``` are supported. \nThe order here is important. That declaration says that our first language is ```English```. So, if nothing\nwas specified by the request, or if these two languages has the same weight on the \nresquest ```Accept-Language``` header, ```English``` will be the choice.  \n\nIf the request specifies an ```Accept-Language``` header, we will choose the language that best fit the\nheader value, considering the list of possible values declared on ```@AcceptLanguage``` decorator.\n\nIf none of our possibilities is good for the ```Accept-Language``` header in the request, the server \nthrows a ```NotAcceptableError``` and returns a ```406``` status code for the client.\n\nYou can decorate methods too, like:\n\n```typescript\n@Path(\"test\")\n@AcceptLanguage(\"en\", \"pt-BR\")\nclass TestAcceptService {\n  @GET\n  @AcceptLanguage(\"fr\")\n  testLanguage(@ContextLanguage language: string): string {\n    // ...\n  }\n}\n```\n\nOn the above example, the list of accepted languages will be ```[\"en\", \"pt-BR\", \"fr\"]```, in that order.\n\nThe ```@Accept``` decorator works exaclty like ```@AcceptLanguage```, but it inform the server about the mime type\nthat a service can provide. It uses the ```Accept``` header in the request to decide about the preferred media to use.\n\n```typescript\n@Path(\"test\")\n@Accept(\"application/json\")\nclass TestAcceptService {\n  @GET\n  testType(@ContextAccept accept: string): string {\n     //...\n  }\n}\n```\n\n### IoC\n\nIt is possible to delegate to [typescript-ioc](https://github.com/d0whc3r/typescript-ioc) the instantiation of the service objects.\n\nFirst, install typescript-ioc:\n\n```sh\nnpm install --save typescript-ioc\n```\n\n\nThen, you can configure it in two ways:\n\n  1. Create a file called ```rest.config``` and put it on the root of your project:\n\n```json\n{\n   \"useIoC\": true\n}\n\n```\n\nor \n\n  2. Proggramatically. Ensure that you call ```Server.useIoC()``` in the begining of your code, before any service declaration\n\n\n```typescript\n/* Ensure to call Server.useIoC() before your service declarations. \nIt only need to be called once */\nServer.useIoC();\n\n@AutoWired\nclass HelloService {\n  sayHello(name: string) {\n    return \"Hello \" + name;\n  }\n}\n\n@Path(\"/hello\")\n@AutoWired\nclass HelloRestService {\n  @Inject\n  private helloService: HelloService;\n\n  @Path(\":name\")\n  @GET\n  sayHello( @PathParam('name') name: string): string {\n    return this.sayHello(name);\n  }\n}\n```\n\n\nIt is also possible to inform a custom serviceFactory to instantiate your services. To do this, \ncall ```Server.registerServiceFactory()``` instead of ```Server.useIoC()``` and provide your own ServiceFactory implementation.\n\nYou can also use the ```serviceFactory``` property in rest.config file to configure it:\n\n\n```json\n{\n   \"serviceFactory\": \"./myServiceFactory\"\n}\n```\n\nAnd export as default your serviceFactory class on ```./myServiceFactory.ts``` file.\n\nIt could be used to allow the usage of other libraries, like [Inversify](http://inversify.io/).\n\n\n### Inheritance and abstract services\n\nIt is possible to extends services like you do with normal typescript classes:\n\n```typescript\n@Path('users')\nclass Users{\n  @GET\n  getUsers() {\n    return [];\n  }\n}\n\n@Path('superusers')\nclass SuperUsers{\n  @GET\n  @Path('privilegies')\n  getPrivilegies() {\n    return [];\n  }\n}\n```\n\nIt will expose the following endpoints:\n\n - ```GET http://<my-host>/users```\n - ```GET http://<my-host>/superusers```\n - ```GET http://<my-host>/superusers/privilegies```\n\n**A note about abstract classes**\n\nA common scenario is to create an abstract class that contains some methods to be inherited by other concrete classes, like:\n\n```typescript\nabstract class MyCrudService<T> {\n\n  @GET\n  @Path(':id')\n  abstract getEntity(): Promise<T>;\n}\n\n@Path('users')\nclass MyUserService<User> {\n\n  @GET\n  @Path(':id')\n  async getEntity(): Promise<User> {\n    return myUser;\n  }\n}\n```\n\nMyCrudService, in this scenario, is a service class that contains some exposed methods (methods that are declared to be exposed as endpoints). However, the intent here is not to expose the method for MyCrudService directly (I don't want an endpoint ```GET http://<myhost>/123``` exposed). We want that only its sublclasses have the methods exposed (```GET http://<myhost>/users/123```).\n\nThe fact that MyCrudService is an abstract class is not enough to typescript-rest library realize that its methods should not be exposed (Once it is compiled to javascript, it becomes a regular class). So you need to explicitly specify that this class should not expose any endpoint directly. It can be implemented using the ```@Abstract``` decorator:\n\n```typescript\n@Abstract\nabstract class MyCrudService<T> {\n\n  @GET\n  @Path(':id')\n  abstract getEntity(): Promise<T>;\n}\n\n@Path('users')\nclass MyUserService<User> {\n\n  @GET\n  @Path(':id')\n  async getEntity(): Promise<User> {\n    return myUser;\n  }\n}\n```\n\nEven if MyCrudService was not a typescript abstract class, if it is decorated with ```@Abstract```, its methods will not be exposed as endpoints.\n\nIf you don't want to use ```@Abstract```, another way to achieve the same goal is to specify which services you want to expose:\n\n```typescript\nlet app: express.Application = express();\nServer.buildServices(app, MyUserService);\n```\n\nor \n\n```typescript\nlet app: express.Application = express();\nServer.loadServices(apis, 'lib/controllers/apis/impl/*');\n```\n\n### Preprocessors\n\nIt is possible to add a function to process the request before the handler on an endpoint by endpoint basis. This can be used to add a validator or authenticator to your application without including it in the body of the handler.\n\n```typescript\nfunction validator(req: express.Request): express.Request {\n  if (req.body.userId != undefined) {\n    throw new Errors.BadRequestError(\"userId not present\");\n  } else {\n    req.body.user = Users.get(req.body.userId)\n    return req\n  }\n}\n\n@Path('users')\nexport class UserHandler {\n  \n  @Path('email')\n  @POST\n  @Preprocessor(validator)\n  setEmail(body: any) {\n    // will have body.user\n  }\n}\n```\n\nPreprocessors can also be added to a class, applying it to all endpoints on the class\n\n```typescript\n@Path('users')\n@Preprocessor(validator)\nexport class UserHandler {\n  \n  @Path('email')\n  @POST\n  setEmail(body: any) {\n    // will have body.user\n  }\n}\n```\n\n## Swagger\n\nTypescript-rest can expose an endpoint with the [swagger](http://swagger.io/) documentation for your API.\n\nFor example: \n\n```typescript\nlet app: express.Application = express();\napp.set('env', 'test');\nServer.buildServices(app);\nServer.swagger(app, './test/data/swagger.yaml', '/api-docs', 'localhost:5674', ['http']);\n```\n\nYou can provide your swagger file as an YAML or a JSON file.\n\nNow, just access: \n\n```\nhttp://localhost:5674/api-docs  // Show the swagger UI to allow interaction with the swagger file\nhttp://localhost:5674/api-docs/json  // Return the swagger.json file\nhttp://localhost:5674/api-docs/yaml  // Return the swagger.yaml file\n```\n\nIf needed, you can provide options to customize the Swagger UI:\n\n```typescript\nconst swaggerUiOptions = {\n  customSiteTitle: 'My Awesome Docs',\n  swaggerOptions: {\n    validatorUrl: null,\n    oauth2RedirectUrl: 'http://example.com/oauth2-redirect.html',\n    oauth: {\n      clientId: 'my-default-client-id'\n    }\n  }\n};\nServer.swagger(app, './swagger.yaml', '/api-docs', undefined, ['http'], swaggerUiOptions);\n```\n\n> See [`swagger-ui-express`](https://github.com/scottie1984/swagger-ui-express) for more options and [`swagger-ui`](https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md) for more `swaggerOptions`. Note: Not all `swagger-ui` options are supported. Specifically, any options with a `Function` value will not work.\n\nTo generate the swagger file, you can use the [typescript-rest-swagger](https://github.com/d0whc3r/typescript-rest-swagger) tool.\n\n```sh\nnpm install typescript-rest-swagger -g\n````\n\n```sh\nswaggerGen -c ./swaggerConfig.json\n```\n\n[typescript-rest-swagger](https://github.com/d0whc3r/typescript-rest-swagger) tool can generate a swagger file as an YAML or a JSON file.\n\n# Breaking Changes\n\nStarting from version 1.0.0, it is required to inform the body type on all ReferencedResources, like:\n\n```typescript\ninterface NewObject {\n   id: string;\n}\n\nclass TestService {\n     @POST\n    test(myObject: MyClass): Return.NewResource<NewObject> {\n        //...\n       return new Return.NewResource<NewObject>(req.url + \"/\" + generatedId, {id: generatedId}); //Returns a JSON on body {id: generatedId}\n     }\n  }\n```\n\nEven when you do not provide a body on a ReferencedResouce, you need to inform ```<void>```\n\n```typescript\nclass TestService {\n     @POST\n    test(myObject: MyClass): Return.RequestAccepted<void> {\n        //...\n       return new Return.RequestAccepted<void>(req.url + \"/\" + generatedId);\n     }\n  }\n```\n","readmeFilename":"README.md"}