1 | # [![Lux](https://lux.postlight.com/src/components/Sidebar/logo.svg)](https://lux.postlight.com)
|
2 |
|
3 | [![CircleCI branch](https://img.shields.io/circleci/project/github/postlight/lux/master.svg?style=flat-square)](https://circleci.com/gh/postlight/lux/tree/master) [![AppVeyor](https://img.shields.io/appveyor/ci/zacharygolba/lux/master.svg?style=flat-square)](https://ci.appveyor.com/project/zacharygolba/lux/branch/master) [![Codecov branch](https://img.shields.io/codecov/c/github/postlight/lux/master.svg?style=flat-square)](https://codecov.io/gh/postlight/lux)
|
4 | [![David](https://img.shields.io/david/postlight/lux.svg?style=flat-square)](https://david-dm.org/postlight/lux) [![npm](https://img.shields.io/npm/v/lux-framework.svg?style=flat-square)](https://www.npmjs.com/package/lux-framework) [![Gitter](https://img.shields.io/gitter/room/postlight/lux.svg?style=flat-square)](https://gitter.im/postlight/lux)
|
5 |
|
6 | A MVC style framework for building highly performant, large scale JSON APIs that anybody who knows the JavaScript language and its modern features will understand.
|
7 |
|
8 | \* _Inspired by [Rails](https://github.com/rails/rails/), [Ember](http://emberjs.com/), and [React](https://facebook.github.io/react/)._
|
9 |
|
10 | **Disclaimer:**
|
11 |
|
12 | This isn't another wrapper around [Express](http://expressjs.com/) or a framework for building frameworks. This also isn't a replacement for server-side frameworks that render DHTML.
|
13 |
|
14 | [Check out the Medium Article!](https://trackchanges.postlight.com/not-another-node-js-framework-33103ebeedf8)
|
15 |
|
16 | ## What?
|
17 |
|
18 | ### Features
|
19 |
|
20 | * Automatic CRUD actions in controllers
|
21 | * Automatic pagination, sorting, filtering via query params in controllers
|
22 | * CLI for eliminating boiler plate
|
23 | * [JSON API](http://jsonapi.org/) 1.0 compliant out of the box
|
24 | * Optimized database queries based on serialized attributes and associations
|
25 | * Highly extensible - just write reusable JavaScript functions
|
26 | * Pairs nicely with client-side JavaScript applications 🍷
|
27 | * Easy to contribute
|
28 | * Routes are stored and accessed via a `Map` not an `Array`
|
29 | * Embraces ES2015 and beyond
|
30 | * Classes
|
31 | * Modules
|
32 | * Promises & async/await
|
33 | * Arrow Functions
|
34 | * etc.
|
35 |
|
36 |
|
37 | ### Philosophies
|
38 |
|
39 | ##### Minimal API surface area
|
40 |
|
41 | Lux uses JavaScript's standard library rather than creating a ton of functions you'll have to learn and remember.
|
42 |
|
43 | After your learn how to use it, you'll rarely need to look at the docs.
|
44 |
|
45 | ##### Pure functions are awesome
|
46 |
|
47 | Or more appropriately somewhat pure functions are awesome.
|
48 |
|
49 | Serving content is done by returning objects, arrays, or other primitives rather than calling `res.end(/* content */);` and returning nothing.
|
50 |
|
51 | ##### Convention over configuration
|
52 |
|
53 | [Rails](http://rubyonrails.org/) and [Ember](http://emberjs.com/) are great because they make hard decisions for you and make it possible to submit a PR on your first day at a new company. This is rare with Node server frameworks.
|
54 |
|
55 |
|
56 | ## Why?
|
57 |
|
58 | Frameworks like Rails are pretty great. You can build amazing applications in a reasonable amount of time without a ton of developers working on a project. They have their limitations though. They can be slow and sometimes hard to scale. Not to mention WebSocket support being so-so.
|
59 |
|
60 | ##### Node to the rescue.
|
61 |
|
62 | It's fast, it allows the developer to get low level with a relatively simple API, WebSockets are stable and supported out of the box, and last but not least it's just JavaScript.
|
63 |
|
64 | ##### Not so fast (metaphorically speaking).
|
65 |
|
66 | The last bit there "It's just JavaScript" has actually been somewhat of a double-edged sword. This has positioned Node as a "great prototyping tool" or "only used for micro services."
|
67 |
|
68 | I can somewhat see why people would think that when returning a list of the first 10 records from a SQL database table looks like this:
|
69 |
|
70 | ```javascript
|
71 | app.get('/posts', (req, res) => {
|
72 | Post.findAll()
|
73 | .then(posts => {
|
74 | res.status(200).json(posts);
|
75 | }, err => {
|
76 | console.error(err);
|
77 | res.status(500).send(err.message);
|
78 | });
|
79 | });
|
80 | ```
|
81 |
|
82 | Could you imagine how ugly that gets when you have to implement pagination, filtering, sorting, or—better yet—formatting the response for JSON API?
|
83 |
|
84 | Also, where does that code live? In what file and folder would I find it? What pattern do you use for organizing this code?
|
85 |
|
86 | 😲Ok ok give me back Rails I'll worry about performance and scaling later. After all, premature optimization is the root of all evil.
|
87 |
|
88 | ##### Problem.resolve();
|
89 |
|
90 | Shouldn't there be a better way to do this? Can't I just return a promise or a JavaScript primitive instead of basically using the native Node http server API?
|
91 |
|
92 | Fortunately ES2015+ has introduced great new features to the JavaScript language, especially when it comes to meta programming.
|
93 |
|
94 | With Lux your code from before can now look like this:
|
95 |
|
96 | ```javascript
|
97 | class PostsController extends Controller {
|
98 | index(req, res) {
|
99 | return Post.all();
|
100 | }
|
101 | }
|
102 | ```
|
103 |
|
104 | Except CRUD actions are taken care of automatically so it would actually look like this:
|
105 |
|
106 | ```javascript
|
107 | class PostsController extends Controller {
|
108 |
|
109 | }
|
110 | ```
|
111 |
|
112 | It's about time a Node server framework learned something from client-side JS frameworks.
|
113 |
|
114 |
|
115 | ## How?
|
116 |
|
117 | ### Installation
|
118 |
|
119 | ```bash
|
120 | npm install -g lux-framework
|
121 | ```
|
122 |
|
123 | ### Creating Your First Project
|
124 |
|
125 | Use the `new` command to create your first project.
|
126 |
|
127 | ```bash
|
128 | lux new <app-name>
|
129 | ```
|
130 |
|
131 | ### Running
|
132 |
|
133 | To run your application use the `serve` command.
|
134 |
|
135 | ```bash
|
136 | cd <app-name>
|
137 | lux serve
|
138 | ```
|
139 |
|
140 | For more information checkout out the [Guides](https://lux.postlight.com/).
|
141 |
|
142 |
|
143 | ## Benchmarks
|
144 |
|
145 | [**postlight/lux-benchmarks**](https://github.com/postlight/lux-benchmarks)
|
146 |
|
147 |
|
148 | ## Contributing
|
149 |
|
150 | ### Installation
|
151 |
|
152 | ```bash
|
153 | git clone https://github.com/postlight/lux
|
154 | cd lux
|
155 | npm install
|
156 | ```
|
157 |
|
158 | ### Testing
|
159 |
|
160 | ```bash
|
161 | git clone https://github.com/postlight/lux
|
162 |
|
163 | # Install Lux dependencies
|
164 | cd lux
|
165 | npm install
|
166 |
|
167 | # Install test app dependencies
|
168 | cd test/test-app
|
169 | npm install
|
170 |
|
171 | # Run the test suite
|
172 | cd ../../
|
173 | npm test
|
174 | ```
|
175 |
|
176 | ## Useful Links
|
177 |
|
178 | * [JSON API](http://jsonapi.org/)
|
179 | * [Knex.js](http://knexjs.org/)
|
180 | * [Chai](http://chaijs.com/) / [Mocha](http://mochajs.org/)
|