Skip to content

RFC: Stix fundamentals

Wesley Overdijk edited this page Sep 19, 2017 · 4 revisions

Stix

The framework itself is basic. It's opinionated towards API-driven development. It will reuse existing modules to make staying up-to-date easier and make it more stable by moving responsibility to the individual dependencies with their own communities (much like wetland heavily depends on knex).

  • Module system
  • Leverage new technologies
  • Lightweight
  • Monitor everything (performance)
  • Full logging control (call stack, what is going on)
  • Fully opt-in
  • No magic (some core modules that can be installed, all very clear and small)

Requests

There's a RequestResolver layer. That's agnostic. You can setup a RestRequestResolver, a GraphQLRequestResolver and a WebsocketRequestResolver. They can run side by side. This allows you to accept different types of requests, but also configure them individually. So, permissions per endpoint type. Or CORS. You decide.

Permissions

There's a Permissions layer that's also agnostic. It supports the default middleware (like policies) or plugins. Plugins could validate permissions by manipulating the QueryBuilder on a per-request basis. So you could set up hierarchical ownership, role based permissions and so on. By making this layer hook in using the opinionated QueryBuilder and Scope on a per-request basis, you are extremely flexible in configuration. This means you can set up very complex, dynamic permission systems that allow you to protect your data in a number of ways.

Module system

This will be the biggest difference with other frameworks.

Everything is module based, and applies IoC. For instance, you could have a Payment module, a Cart module and an Inventory module. On top of that, you use a Webshop module that uses the other ones. The Cart module expects an Entity to exist that has the id Product. It has a relation with it. So, Inventory could expose it, but you can easily overwrite it in your application with let's say an Item Entity. IoC is applied through config merging (hello Homefront) left to right. So local > app > module. This allows for very fast scaffolding of APIs, given that the modules are configurable enough. This is a lot like machinepacks, in the sense that it should be drop-in and play. Here we can set up default configuration formats so our CLI can ask questions when installing (to configure the module for your app, much like Symfony does with Bundles).

Database

The data layer depends on Wetland. We either build an ODM (should be simple enough, we could even use waterline under water) or allow for other plugins to be used as well. All this would require is a Scope-like interface and a Repository-like interface.

Resources

Resources will be split up in modules, even in your application. So you'll end up with pretty much the same structure a default sails app has (with wetland), but per resource you'll have a directory with the same structure, its own config, etc. That way you can more nicely group code together. This means you'll end up with something like this:

.
├── config
├── app
│   ├── config
│   ├── controller
│   ├── entity
│   ├── repository
│   └── service
├── cart
│   ├── config
│   ├── controller
│   ├── entity
│   ├── repository
│   └── service
├── inventory
│   ├── config
│   ├── controller
│   ├── entity
│   ├── repository
│   └── service
└── user
    ├── config
    ├── controller
    ├── entity
    ├── repository
    └── service

Response

Then there's a Response layer. You can hook in to this part in your application, if you want. This is configurable as well. So if you want to do something crazy, you could accept a GraphQL type request, but respond in a Restful manner (provided there are no conflicts in structure). This is the same as the sails responses directory essentially and installable as a plugin (for sensible defaults for Rest, GraphQL etc).

Monitoring

Every module is responsible for logging using a predefined API. This too will be a plugin but can be swapped out. I want to use Winston for this as it supports many transports. Using this you have control over every part of your application, and we can offer filtering based on module, log level, and even tags applied by the logging targets.

Clone this wiki locally