- Automatic route generation
- Production bundling and build generation
- File-watching and automatic restarts via Denon
- Request tracing support
- Unit tests
To install Deno follow the setup guide found here. If you are using an IDE such as VS Code, Atom, Visual Studio or a JetBrains product, make sure to install the appropriate Deno plugin and update ts-config.json
if required. A working community-developed plugin can be found here.
To test drive a production build of this server run the following command after installing Deno.
$ deno run --allow-net https://damianperera.github.io/deno-starter/server.bundle.js
Install the development dependencies to enable file-watcher and automatic restarts on code changes.
$ ./deno install
Execute the following command in your terminal to start the local server.
$ ./deno run
Execute the following command in your terminal to bundle your source files and dependencies, compile the TypeScript files and create a server.bundle.js
file in the build/
directory.
$ ./deno build
Execute the following command in your terminal to start the production build of the server. As mentioned in the Build section, since the production build is a bundle of all the application sources and third-party modules you can directly run it without compiling the TypeScript sources or downloading any of the dependencies.
$ deno run --allow-net build/server.bundle.js
Execute the following command in your terminal to run the unit test suite.
$ ./deno test
Tests are written in a separate folder in order to maintain a logical seperation between the source and testing layers.
Start the server and execute the following command in your terminal to execute the integration test suite.
$ ./deno integration
Integration tests can be found in the integration/
directory. These are very rudimentary cURL tests that execute requests against the configured endpoints.
When using this boilerplate your starting point for a REST API endpoint would be the src/controllers/
directory.
- src
|- controllers
|- health.ts
|- products.ts
|- accounts.ts
The controllers
directory contains the route declaration of your REST service. For each file in this directory an automatic base path will be generated.
For example, specifying a new file named orders.ts
inside the controllers
directory with a default export of type Array<Routes.Endpoints>
will automatically create the base path /api/v1/orders
and configure any endpoint path
specified in the controller on top of the base path like /api/v1/orders/summary
.
Since Deno is a secure runtime for JS you need to explicitly give scripts the permission to do certain 'privileged' actions, such as access the network. This server requires the --allow-net
and --allow-read
permissions out of the box.
--allow-net
: Being a REST service this is required in order to bind a port and access the network. You can make the permission level more granular by specifying the networks that the service has access to (e.g.--allow-net:0.0.0.0
) in the./deno
executable.--allow-read
: Since the route manager automatically configures endpoints based on filenames and their contents, the server needs read access to the filesystem. You can make the permission level more granular by allowing read access only to the server's root directory instead of the entire filesystem by specifying--allow-read=./
in the./deno
executable.--allow-write
: Required in order to generate theroutes.ts
file in thesrc/config/
directory.
You can refer the TS files in the source directories for absolute file paths usage such as service/interface/...
instead of relative file paths such as ../../interface/...
. The paths are configured inside src/config/absolutePaths.json
.
You can pass in Deno args such as additional permissions by simply appending them to the run
or test
commands - e.g. to grant permission to read environment variables you can execute the following command:
$ ./deno run --allow-env
A Correlation ID is generated for every request and injected into the request headers if value of the CORRELATION_ID_HEADER
variable in src/constants.ts
is not found in the incoming request.
- Asynchronous middleware support in controllers (passing in multiple functions to serve as middleware instead of a single function)
- Unit tests for framework files (
http.ts
,generator.ts
) - Custom logger (to wrap logs and output JSON logs to stdout)