Giter VIP home page Giter VIP logo

snakey's Introduction

Snakey is a Observer-based web microframework for Node.js, built using Rxjs. Inspired by Express.js.

Why?

I love Express.js. I love how simple it is to get an application up and running, but I dislike using callbacks for everything, and I dislike imperative programming. I searched far and wide for a callback-free web framework for Node.js, and was disappointed when I was unable to find anything. Thus, Snakey was born.

Snakey is for people like me who want to prevent themselves from getting trapped in Callback Hell, and also want to reap the benifits of Javascript's functional programming capabilities.

Installation

Note that Snakey is still very much experimental.

npm install snakey

or

yarn add snakey

Roadmap

  • Convert url-params to TypeScript
  • Add a functional API for building responses

Documentation

Quickstart

Snakey provides you with an Observable stream of HTTP requests, and functional programming tools to shape the stream into whatever your app needs.

import {of} from 'rxjs';
import {bite, snake, Context, applySnakes} from 'snakey';
import {textResponse} from 'snakey/response';

const app = [
  snake<Context>()
    .chain(bite('GET', '/'))
    .chain(textResponse('Hello World!'))
];

const {server} = applySnakes(app);
server.listen(9000);

Snakes

At the core of Snakey is the Snake type. A Snake is simply an OperatorFunction with a chain method. chain composes the Snake with a given OperatorFunction to form a new Snake. Because Snakes build on each other, this effectively creates a type-safe series of Operators.

export interface Snake<T, R> extends OperatorFunction<T, R> {
    chain<N>(op: OperatorFunction<R, N>) : Snake<T, N>
}

Creation

Snakes can be created using the snake function. This function takes an optional OperatorFunction and lifts it to a Snake.

import {snake} from 'snakey/snake';
import {map} from 'rxjs/operators';

snake<String>(); // Snake<String, String>
snake<Number, String>(map(n => String(n))); // Snake<Number, String>

applySnake

The applySnake function takes an array of Snakes and generates multiple Observables for each Snake. These Observables are then connected to a Node http.Server, and subscribed to.

export function applySnakes(snakes: Snake<Context, Responder>[], 
                            server: Server = new Server(),
                            observer = new ResponderObserver): SnakeResult;

The return value of applySnake is an object of three fields that contain the server, the generated Observables and the Subscriptions.

export type SnakeResult = {
  server: Server,
  streams: Observable<any>[]
  subscribers: Subscription[]
}

You can supply your own Observer to use, but the default behavior is to call a function. This does mean that your Streams should eventually return a function. This function is referred to as the Responder.

Context

The beginning of all requests is Context. applySnake automatically converts all requests into Context objects.

Properties

attributes name type description
readonly request http.IncomingMessage The request object recieved from Node.
readonly response http.ServerResponse The response object recived from Node.
readonly uri uri-js:URIComponents Parsed request URI.
readonly pathMatch PathMatch RegExpExecArray

Methods

match(pattern: string | RegExp): Context

If uri.path matches pattern a new Context object with pathMatch set will be returned. Otherwise, this will be returned.

bite(verb: string, pathPattern: string | RegExp)

bite is an operator for Observable<Context>. It creates an Observable<Context> that matches the verb and pathPattern. Path matching is done using Context.match, so any parameters or RegEx groups are preserved in the pathMatch property of Context.

Responder

Snakey provides its own objects for writing responses to client. The one you'll likely be using most oftens is the Responder class. Indeed, this expected return value for every Snake.

The Responder class is simply the collection of data needed to construct and send a response to the client. It provides at least one method: respond which constructs and sends this response. This method is called by the default Observer.

Properties

attributes name type description
readonly resObj http.ServerResponse The response object recieved from Node.
readonly body string {toString(): string}
readonly status number The HTTP status code of the response to send to the client. (default: 200)
readonly headers HeaderMap The HTTP headers to write to the client.
readonly encoding string The encoding of the body. (default: 'UTF-8')
readonly endResponse bool If true, the call to respond will terminate the connection with the client. (default: true)

response(): void

Writes the HTTP response to the client. If endResponse evaluates to true the connection will be terminated.

snakey's People

Stargazers

 avatar

Watchers

 avatar  avatar

Forkers

faithanalog

snakey's Issues

Implement a default way to handle invalid URLs

bite is currently just a normal operator that operates on Observable<Context> and filters out all requests that don't match the HTTP method and path pattern. However, no mechanism currently exists to obtain requests that haven't matched any filters.

This is an issue because as it stands, Snakey has no way to return 404s on requests which do not match any url patterns. The current behavior hangs the connection indefinitely.

I like bite being a simple functional operator, and how it is currently used, however, it may be the case that bites api and the implementation of applySnakes might need to be adjusted.

Ideally the default behavior of snakey should be to obtain unmatched requests and return 404 responses.

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.