Skip to main content
Deno 2 is finally here 🎉️
Learn more

Jurassic Logo

🦖 Jurassic

A Straightforward REST API Framework for Deno. Zero-config server with path-based router.

Features

✅ Zero-Config framework
✅ Instant path-based routing
✅ Dynamic route params with filename
✅ Hooks and Plugins

Table of Contents

Table of Contents

Getting Started

Build an API server should be easy not a complex things. As developer, often we are struggle to build an API server, most of our time was used to restructure file and and refactor codes.

As business process evolve, more weird and complex things appears, and it’s not a pokemon, but problem that we always hate.

And we don’t remember where is the code and what the file for.

We’re having a bad time, and after somewhile, you open old legacy codes, you feels like “who wrote this ugly codes?,” it’s cliché, doesn’t it?

Today, developer forgot to write simple codes and file structure that every developers can read and mantain.

We’re all love simplicity. And this framework exists.


Basic Usage

As long as you have deno installed, and favourite code editor, you can start right away. How to start the server? let’s don’t skip reading this documentation.

Routers

You don’t need to create bootstrap file like any other frameworks.

Just add routes folder in your current working directory.

After that, add a hello.ts file as your first router, and you’re done.

Example Code
// <your_current_directory>/routes/hello.ts
import {
  HttpRequest,
  HttpResponse,
} from "https://deno.land/x/jurassic/@types/http.d.ts";

// Route Handler
export default (req: HttpRequest, res: HttpResponse) => {
  return "Hello world";
};

Run Server

Type this command in your current directory, from your favourite terminal.

deno run --allow-read --allow-net --allow-env https://deno.land/x/jurassic/server.ts

If you see log below, then your server is running successfuly.

Console Log
🦖 Start jurassic server
-------------------
[server info]
PORT: 8888

[routes]
- /hello
-------------------

Now access test in your browser http://localhost/hello.

Dynamic Route Params

I believe building REST API router should be easy. As NextJS developer, I’m inspired by NextJS API directory, using bracket filename as dynamic routes params.

To create a dynamic route with params, just use bracket as directory or file name e.g [type]/[slug].ts. You can use it as nested directory too.

You can accessing param within route handler with req.params, e.g req.params.myParams.

Example Code
// <your_current_directory>/routes/post/[id].ts
import {
  HttpRequest,
  HttpResponse,
} from "https://deno.land/x/jurassic/@types/http.d.ts";

export default (req: HttpRequest, res: HttpResponse) => {
  return `Post ID: ${req.params.id}`;
};

Router Methods

By default your router will accepts all methods (GET, POST, PUT, OPTIONS, DELETE), but you can define or restrict it, to do that just export method variable. It support array or string.

Example Code
// <your_current_directory>/routes/v1/your-router.ts
import {
  HttpRequest,
  HttpResponse,
} from "https://deno.land/x/jurassic/@types/http.d.ts";

export const method = ["GET", "POST"];
// or
// export const method = "POST"

export default (req: HttpRequest, res: HttpResponse) => {
  return `Method ${req.method}`;
};

Multiple Handler

In the previous section you can define or restrict router methods, but what if every method have different response or consume different database / service. You can use multiple handler:

Example Code
// <your_current_directory>/routes/v1/your-router.ts
import { HttpRequest, HttpResponse } from "https://deno.land/x/jurassic/@types/http.d.ts";

export const method = ["GET", "POST"];

export default {
  get(req: HttpRequest, res: HttpResponse) => {
    return `GET response`;
  },

  post(req: HttpRequest, res: HttpResponse) => {
    return `POST response`;
  }
};

Overrides Header

Example Code
// <your_current_directory>/routes/v1/your-router.ts
import {
  HttpRequest,
  HttpResponse,
} from "https://deno.land/x/jurassic/@types/http.d.ts";

export const headers = {
  // your http header here
};

export default (req: HttpRequest, res: HttpResponse) => {
  return `My Router`;
};

Set Content Type

You can set Content-Type in headers or contentType variable. The difference is contentType use shortcut.

Example Code
// <your_current_directory>/routes/hello.ts

import {
  HttpRequest,
  HttpResponse,
} from "https://deno.land/x/jurassic/@types/http.d.ts";

// You can set content type with headers.
export const headers = {
  ["Content-Type"]: "application/json",
};

// Or you can use shortcut.
export const contentType = "json";

export default (req: HttpRequest, res: HttpResponse) => {
  return {
    hello: "world",
    universe: true,
    cluster: "lineakia",
  };
};

Router Best Practice

Use versioning path in your router for best practice. When you’re upgrading API version, developer or API consumer won’t get confused.

But it’s okay if you define static route, such as ping or health (for health check API).

❌ /routes/post/[id].ts
❌ /routes/cart/[id].ts

✅ /routes/ping.ts
✅ /routes/health.ts
✅ /routes/v1/post/[id].ts
✅ /routes/v2/users.ts
✅ /routes/v2/user/@[id].ts
✅ /routes/v2/user/[dynamic].ts

Custom Config

You can change port and add environment to your project. Create a server.ts file in your directory. And export port / env file. We added SERVER_ENV_ to your environment.

Example Code
// <your_current_directory>/server.ts
// Custom PORT
export const port = 3000;

// Environment
export const env = {
  MY_KEY: "secret-key",
};

// <your_current_directory>/routes/hello.ts
// access environment
Deno.env.get("SERVER_ENV_MY_KEY");

Examples

See example codes in Examples directory.

License

MIT - 2020 (c) oknoorap. More details see LICENSE file.