Coder Social home page Coder Social logo

aqua's Introduction

Aqua

Aqua is a minimal and fast web framework.

Features

  • Built-in cookie, header, file, query, and body parsing
  • Middleware functions
  • URL parameters
  • Usage of the native HTTP server API
  • Deno Deploy support

Example usage

Please make sure to have at least Deno version 1.13 installed.

import Aqua from "https://deno.land/x/aqua/mod.ts";

const app = new Aqua(3100);

app.get("/", (req) => {
  return "Hello, World!";
});

Routing

You can either use the short-form syntax for the GET, POST, PUT, PATCH and DELETE method

app.get("/", (req) => "Hello, World!");
app.post("/", (req) => "Hello, World!");
app.put("/", (req) => "Hello, World!");
app.patch("/", (req) => "Hello, World!");
app.delete("/", (req) => "Hello, World!");

or use the route function

app.route("/", "GET", (req) => "Hello, World!");

Schemas

Schemas will discard non-matching requests (Defined fallback handler or default 404).

app.get("/", (req) => {
  return "Hello, World!";
}, {
  schema: {
    query: [
      mustExist("hello"),
      (query) => query.hello !== "world",
    ],
  },
});

This schema would only allow requests with the hello query present and the value not being "world" (for example, GET /?hello=yes). The following helper functions are currently available:

  • mustExist(key)
  • valueMustBeOfType(key, type)
  • mustContainValue(key, values)

You can of course also build your own schema validation functions. Here's how the mustExist function looks:

function mustExist(
  key: string,
): RoutingSchemaValidationFunction<Record<string, unknown>> {
  return (context) => {
    /**
     * `context` could either be a `cookies`,
     * `parameters`, `headers`, `query` or `body` object.
     */
    return Object.keys(context).includes(key);
  };
}

Middlewares

You can register middlewares, that will be able to adjust the response object, the following way. Thereby you can decide whether you would like to modify the outgoing or incoming request.

app.register((req, res) => {
  /**
   * Ignore non-text responses:
   * if (typeof res.content !== "string") return res;
   *
   * res.content = res.content.replace("Hello", "Hi");
   */
  return res;
}, MiddlewareType.Outgoing);
app.register((req) => {
  /**
   * req.query.hello = "world";
   */
  return req;
}, MiddlewareType.Incoming);

URL parameters

You can define URL parameters by using a colon followed by the key name.

app.get("/api/:action", (req) => {
  return req.parameters.action;
});

Response value

You can either just return a string

app.get("/", (req) => {
  return "Hello, World!";
});

or return a response object to also set cookies, headers or a status code

app.get("/", (req) => {
  return {
    statusCode: 200,
    cookies: { hello: "I'm a cookie value" },
    headers: { hello: "I'm a header value" },
    content: "Hello, World!",
  };
});

Cookies and headers are just getting appended, so no information is getting lost by providing custom ones. However, you can still overwrite existing headers.

More examples

Provide own fallback handler

Your provided fallback handler will be executed if no route has been found.

app.provideFallback((req, errorType) => {
  if (
    errorType === ErrorType.NotFound || errorType === ErrorType.SchemaMismatch
  ) {
    return "No page found, sorry!";
  }

  // Provide no custom fallback response for other error types
  return null;
});

Redirect a request

app.get("/dashboard", (req) => {
  return { redirect: "/login" };
});

Static routes

You can register static routes by passing the path to the local folder and the public alias to the serve function.

app.serve("mystaticfolder", "/public");
// A GET request to /public/test.txt would serve the local file at mystaticfolder/test.txt

Regex paths

You can provide a RegExp object instead of a string and receive the matches.

app.get(new RegExp("\/(.*)"), (req) => {
  console.log(req.matches); // GET /hello-world -> [ "hello-world" ]

  return "Hello, World!";
});

TLS

You can enable TLS the following way:

const app = new Aqua(3001, {
  tls: {
    hostname: "localhost",
    certFile: "localhost.crt",
    keyFile: "localhost.key",
  },
});

The example above would handle requests coming to https://localhost:3001.

Handle HTTP and HTTPS requests

You are able to provide the TLS certificate to a different port and let the default port still handle HTTP requests.

const app = new Aqua(3001, {
  tls: {
    hostname: "localhost",
    certFile: "localhost.crt",
    keyFile: "localhost.key",
    independentPort: 3002,
  },
});

The example above would allow you to handle requests to http://localhost:3001 and https://localhost:3002 at the same time.

File uploading

app.post("/upload", async (req) => {
  const { newProfilePicture } = req.files;
  await Deno.writeFile(
    newProfilePicture.name,
    new Uint8Array(await newProfilePicture.arrayBuffer()),
  );

  return "Uploaded!";
});
import Aqua from "https://deno.land/x/aqua/deploy.ts";
//                                         ^^^^^^^^^

const app = new Aqua();
//                  ^^ (No port)

app.get("/", (req) => {
  return "Hello, World!";
});

Yes, that's it. Everything else should work as you are used to. :)

Streaming

app.get("/", (req) => {
  const stream = new ReadableStream({
    start(controller) {
      let i = 0;
      const interval = setInterval(() => {
        controller.enqueue(new TextEncoder().encode("hello world!"));

        if (i === 9) {
          clearInterval(interval);
          controller.close();
        }

        i++;
      }, 500);
    }
  });

  return {
    content: stream,
    headers: {
      "Content-Type": "text/html"
    }
  };
});

aqua's People

Contributors

gr7d avatar mocoso avatar shyim avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.