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 igaIn 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:/fooroutes/foo/bar.js:/foo/barroutes/also-typescript.ts:/also-typescript
By default, iga allows you to write your code in es5 module.exports, es6 export defaultor 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
falseeverytime you change your code you will be able to see the new version on the server This is whatigacommand 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 |