0.0.106 • Published 27 days ago

dorsale v0.0.106

Weekly downloads
-
License
MIT
Repository
github
Last release
27 days ago

dorsale

Dorsale is an attempt at creating a TS equivalent of Spring for Java. It is built on top of Fastify and uses decorators to define elements of your application.
It is a work in progress, and is not ready for production use. If you benchmark it, please let me know the results!

Installation

Dorsale is available on npm. You can install it with:

npm install dorsale

Getting started

Bootstrapping

The setup is intentionally minimalistic. Bootstrapping a Dorsale application is as simple as:

import { dorsale } from 'dorsale';

dorsale({ port: 8080 });

This will start a server on port 8080. You can then add controllers, services, and repositories to your application.

Full application example

A full example could look like this:

src
├── index.ts
├── user.ts
├── userFinder.ts
├── userManager.ts
├── userController.ts
// index.ts
import { dorsale } from 'dorsale';

dorsale({ port: 8080 });
// user.ts
export interface User {
  id: string;
  email: string;
  password: string;
}
// userFinder.ts
import { User } from "./user";

export interface UserFinder {
  findAllUsers(): Promise<User[]>;

  findUserById(id: string): Promise<User | undefined>;

  findUserByEmail(email: string): Promise<User | undefined>;
}
// userManager.ts
import { UserEditor } from "./userEditor";
import { UserFinder } from "./userFinder";
import { User } from "./user";
import { Component } from "dorsale";

@Component
export class UserManager implements UserFinder {
  users: User[] // = [... some users];

  findAllUsers(): Promise<User[]> {
    return Promise.resolve(this.users);
  }

  findUserByEmail(email: string): Promise<User | undefined> {
    const user = this.users.find((u) => u.email === email);
    return Promise.resolve(user);
  }

  findUserById(id: string): Promise<User | undefined> {
    const user = this.users.find((u) => u.id === id);
    return Promise.resolve(user);
  }
}
// userController.ts
import { Controller, Get } from "dorsale";
import { UserFinder } from "./userFinder";

@Controller()
export class UserController {
  constructor(private readonly userFinder: UserFinder) {
  }

  @Get("/")
  getAll() {
    return this.userFinder.findAllUsers();
  }

  @Get("/:id")
  getById(id: string) {
    return this.userFinder.findUserById(id);
  }
}

You just have to run the file containing the dorsale call, and you're good to go! The other components will be automatically discovered and injected. This reduces the amount of boilerplate code you have to write. By default, Dorsale will look for components in the src folder, but you can change this by passing a rootDir option to the dorsale call.

dorsale({ port: 8080, rootDir: "myFolder/relative/to/the/current/file" });

Controllers

Controller classes

Controllers are classes that define the routes exposed by your application. They are decorated with @Controller().

import { Controller } from "dorsale";

@Controller()
export class UserController {
    // ... your routes
}

You can also specify a prefix for all the routes defined in a controller by passing it as an argument to the decorator.

@Controller("/users")
export class UserController {
    // ... your routes
}

Routes

Routes are defined by decorating methods with @Get, @Post, @Put, @Patch, or @Delete.

import { Controller, Get } from "dorsale";

@Controller()
export class UserController {
    @Get("/hello")
    getHello() {
        return "Hello world!";
    }
}

In the example above, a GET route will be exposed at /hello, and will return the string "Hello world!".

Route parameters

You can define route parameters by adding a colon (:) before the parameter name in the route path.

import { Controller, Get } from "dorsale";

@Controller()
export class UserController {
    @Get("/users/:id")
    getUserById(id: string) {
        // ...
    }
}

Query parameters

Query parameters are defined by adding a @Query decorator to the parameter.

import { Controller, Get, Query } from "dorsale";

@Controller()
export class UserController {
    @Get("/users") // e.g. GET /users?page=1&limit=10
    getUsers(@Query page: number, @Query limit: number) {
        // ...
    }
}

If some query parameters are not provided in the request, they will be undefined.

Body

You can access the body of the request by adding a @Body decorator to a parameter.

import { Controller, Post, Body } from "dorsale";

@Controller()
export class UserController {
    @Post("/users")
    createUser(@Body user: User) {
        // ...
    }
}

Body validation

You can validate the body of a request by adding a @BodySchema decorator to a route.

import { Controller, Post, Body, BodySchema } from "dorsale";

@Controller()
export class UserController {
    @Post("/users")
    @BodySchema({
        type: "object",
        properties: {
            email: { type: "string" },
            password: { type: "string" },
        },
        required: ["email", "password"],
    })
    createUser(@Body user: User) {
        // ...
    }
}

This uses Fastify's JSON Schema validation.

Testing

Coming soon!

Contributing

Contributions are welcome! Feel free to open an issue or a PR if you have any suggestions or bug reports. Please follow the GitHub flow when contributing (see here for more information). Thanks for your interest in Dorsale!

0.0.106

27 days ago

0.0.105

27 days ago

0.0.104

1 month ago

0.0.103

2 months ago

0.0.102

2 months ago

0.0.97

2 months ago

0.0.98

2 months ago

0.0.99

2 months ago

0.0.101

2 months ago

0.0.100

2 months ago

0.0.96

2 months ago

0.0.95

2 months ago

0.0.94

2 months ago

0.0.91

3 months ago

0.0.92

3 months ago

0.0.93

3 months ago

0.0.88

3 months ago

0.0.89

3 months ago

0.0.90

3 months ago

0.0.84

3 months ago

0.0.85

3 months ago

0.0.86

3 months ago

0.0.87

3 months ago

0.0.83

3 months ago

0.0.81

3 months ago

0.0.82

3 months ago

0.0.80

3 months ago

0.0.78

3 months ago

0.0.79

3 months ago

0.0.73

3 months ago

0.0.74

3 months ago

0.0.75

3 months ago

0.0.76

3 months ago

0.0.77

3 months ago

0.0.72

3 months ago

0.0.70

4 months ago

0.0.71

4 months ago

0.0.62

4 months ago

0.0.63

4 months ago

0.0.64

4 months ago

0.0.65

4 months ago

0.0.66

4 months ago

0.0.61

4 months ago

0.0.60

4 months ago

0.0.59

4 months ago

0.0.55

4 months ago

0.0.56

4 months ago

0.0.57

4 months ago

0.0.58

4 months ago

0.0.51

4 months ago

0.0.52

4 months ago

0.0.53

4 months ago

0.0.54

4 months ago

0.0.50

4 months ago

0.0.48

5 months ago

0.0.49

5 months ago

0.0.45

5 months ago

0.0.46

5 months ago

0.0.47

5 months ago

0.0.42

5 months ago

0.0.43

5 months ago

0.0.44

5 months ago

0.0.41

5 months ago

0.0.40

5 months ago

0.0.34

5 months ago

0.0.35

5 months ago

0.0.36

5 months ago

0.0.33

5 months ago

0.0.21

5 months ago

0.0.22

5 months ago

0.0.23

5 months ago

0.0.24

5 months ago

0.0.25

5 months ago

0.0.18

5 months ago

0.0.30

5 months ago

0.0.31

5 months ago

0.0.32

5 months ago

0.0.26

5 months ago

0.0.27

5 months ago

0.0.28

5 months ago

0.0.29

5 months ago

0.0.12

5 months ago

0.0.13

5 months ago

0.0.14

5 months ago

0.0.3

5 months ago

0.0.15

5 months ago

0.0.9

5 months ago

0.0.16

5 months ago

0.0.17

5 months ago

0.0.5

5 months ago

0.0.4

5 months ago

0.0.7

5 months ago

0.0.6

5 months ago

0.0.2

11 months ago