@starscream/core
v0.2.4
Published
Starscream is an small, opinionated framework ontop of Fastify, almost like a distribution. It includes a bunch of plugins, sets up sensible defaults, and wires things together so you can work in a convention over configuration style. It aims to be the mo
Downloads
1,571
Readme
Starscream - Batteries Included Fastify
Starscream is an small, opinionated framework ontop of Fastify, almost like a distribution. It includes a bunch of plugins, sets up sensible defaults, and wires things together so you can work in a convention over configuration style. It aims to be the most productive tool for building API driven web services, including all the other little bits that don't happen to exactly be APIs.
Status
Still pretty Gadget specific. Mostly used as a place to pull out code that feels general into a shared spot. Not really a framework yet, but handy for demarcating between Gadget API specific stuff and Good Web Server specific stuff.
Features
- TypeScript everywhere
- Centralized, multi-environment, user extensible configuration
- File based Fastify plugin registration with scoping contexts
- pnpm workspace based development workflow
- Good testing support via transactional fixtures and integration testing sessions (with
fastify.inject
)
Included Plugins
@fastify/secure-sessions
for sessions@fastify/view
for view rendering@fastify/websocket
for websocketstypeorm
for database connectivity- etc, see
boot.ts
File Based Routes with Scope
Starscream uses a filesystem based router similar to next.js where each HTTP route is a separate file on disk, and the file's path governs the HTTP path pattern that runs the code in the file. For example, you might have this folder structure:
src/
routes/
GET-home.ts
GET-posts.ts
POST-posts.ts
posts/
GET-[id].ts
This would register routes for GET /home
, GET /posts
, POST /posts
, and GET /posts/:id
with Fastify. Starscream uses this convention so that it's always easy to find the file that powers a given route in a project, and also so that routes can be lazily required, improving boot and reboot performance in development. A route file is a file which exports an async route handler function like this:
import { StarscreamRoute } from "@starscream/core";
const route: StarscreamRoute = async (request, reply) => {
await reply.send({ pong: request.ip });
};
export default route;
If you want to add route options to a route like route hooks, route schema, or route constraints, you can do that by setting the options
property on the route object like so:
import { StarscreamRoute } from "@starscream/core";
const route: StarscreamRoute = async (request, reply) => {
// some useful stuff
};
route.options = {
preValidation: someAuthHook,
constraints: { host: "one-specific-domain.com" },
// and all the other fastify route options here: https://www.fastify.dev/docs/latest/Reference/Routes/#routes-option
};
export default route;
File Based Fastify Plugins
Fastify has a plugin encapsulation feature where registered hooks, decorators, or other required plugins apply only to the other stuff registered within that plugin and not outside it. This is really useful for isolation and composition -- if you want to run a hook for user authentication for example, you can add it in an outer plugin, and all routes added to that plugin or inner plugins will run the hook.
To make encapsulation easy and predictable, Starscream maps each folder of routes on the filesystem to a new plugin encapsulation context. So, hooks added to one folder of routes apply to all the routes within that folder, but not to routes in other folders.
Plugin files must start with a +
character. This shows Starscream you mean for it to be a plugin file and not a route. Files that aren't routes and aren't plugins aren't allowed in the src/routes
directory -- they can go anywhere else in src
and be imported by routes or plugins just fine.
For example, if you had this folder structure:
src/
routes/
GET-home.ts
GET-posts.ts
+scope.ts
posts/
GET-[id].ts
+scope.ts
Hooks or decorators defined in src/routes/scope.ts
will apply to all routes, and then hooks or decorators defined in src/routes/posts/+scope.ts
will only apply to routes src/routes/posts
.
Plugins are one source file that exports an async function which is passed the server
instance the plugin should work with. They look like this:
import { StarscreamPlugin } from "@starscream/core";
const scope: StarscreamPlugin = async (server) => {
server.decorateRequest("myCoolRequest", true);
};
export default scope;
Plugin files can do anything normal Fastify plugins can, and are eager loaded during development to ensure any setup they do is applied before routes start getting run. Plugins are the right place to register other plugins.
Config
Starscream exports a Config
object which has both starscream's configuration and your app's configuration on it. Set config in starscream.config.ts
which will be auto required from the root of the api
project. If you have a starscream.config.local.ts
it will also be auto required and merged into the final Config
object.
Handy config doodads:
Config.env
has anEnvironmentName
object that has aname: string
as well astestLike()
orproductionLike()
interrogatorsConfig.app
has your app's configuration
Starscream also replaces TypeORM's config management facilities with it's own, so configure TypeORM with Config.database
. To use secrets in production for the config, reference them in the starscream.config.ts
file like you might any other environment variable with process.env['SOME_SECRET_VAR']
.
Utilities
inlineOperation
Useful for booting up the application but not actually starting the server in order to do useful stuff, like seed the database or run a migration.