Zero config typescript/es6 server with the filesystem as the router
Inspired by NextJS, iga
exposes a lightweight server using your file system as a router.
- One command
- 0 config ES6 modules
- Typescript out of the box
- Use the file system as the router
- Automatic code reloading
npm install iga
In your package.json
:
{
"scripts": {
"dev": "iga",
"start": "iga start"
}
}
Then create a routes
folder with an index.js
. Each route should export a function with the standard NodeJS request
and response
objects with some helpers.
// routes/index.js
export default () => 'Hello from iga!'
If you run npm start
and you visit http://localhost:3000 you will see Hello from iga!
.
Now let's create another endpoint. Create a file routes/random-fruit.js
:
// routes/random-fruit.js
export default () => {
const fruits = ['apple', 'orange', 'pear']
const random = Math.floor(Math.random() * 3)
return fruits[random]
}
Now if you run npm start
again and visit http://localhost:3000/random-fruit you will get any of the fruits we declared in the file.
If you don't want to restart the server everytime you make changes, use npm run dev
to disable cache and see the latest changes to your code.
iga
catches the return value of your function and makes an http response with it, so you can do things like:
return 'some text'
: Response will be plain textreturn { foo: bar }
: Response will be JSONreturn 403
: Response will send a 403 status code
If you still want to do something manually, you can use both request
and response
objects, like:
export default (req, res) => {
res.end(`Hello from ${req.url}`)
}
In this case the return value will be ignored, because http headers have already been sent with res.end
.
request.query
Contains the result of require('url').parse(req.url, true).query
, so you can code faster:
// routes/find-user.js
export default req => {
if (!req.query.userId) {
return 403 // bad request
}
const user = getUserFromDatabase({ id: req.query.userId })
if (!user) {
return 404 // not found
}
return { results: [user] }
}
As you might have noticed by the previous examples, iga
convers your file system into routes as follows:
routes/index.js
:/
routes/foo.js
:/foo
routes/foo/bar.js
:/foo/bar
routes/also-typescript.ts
:/also-typescript
By default, iga
allows you to write your code in es5 module.exports
, es6 export default
or even typescript, with 0 configurations, thanks to sucrase. For .js
files it will allow you to write es6 modules, but you can also directly write typescript in .ts
files.
import { ServerResponse, IncomingMessage } from 'http'
export default function(req: IncomingMessage, res: ServerResponse) {
res.end('hello from typescript.ts')
}
If you want to, your exported function can be an async
function so you can use await
inside it to manage promises.
iga
Without any arguments, iga
will build your project everytime there's a change in your routes
folder, so you can focus on coding.
iga start
It will start the server without rebuilding. This should be used in production.
-p | --port XXXX
Optional. Start the server on port XXXX
. Defaults to 3000.
iga
exposes an API so it's easier to test and use as a library:
import iga from 'iga'
import http from 'http'
const server = new http.Server(iga)
If you want, there are some options you can customize:
import { getMiddleWare } from 'iga'
import http from 'http'
const server = new http.Server(
getMiddleWare({
routes: __dirname,
useCache: false
})
)
Path to the folder that contains your routes
Default: path.join(process.cwd(), 'routes')
If
false
everytime you change your code you will be able to see the new version on the server This is whatiga
command uses with no arguments
Default: true
Any provider that can run NodeJS will work. If you want to use now.sh, I made a simple example that works. It uses deploy.js
as the lambda in now.sh.
MIT
Pablo Varela |