You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/docs/getting-started/project-structure.md
+17-17Lines changed: 17 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,39 +4,39 @@ sidebar_position: 2
4
4
5
5
# project structure
6
6
7
-
this is an overview of each directory in the project and what it is for. this is also the directories present after initialization.
7
+
this is an overview of each directory in the project and what it is for. this is also the directories present after initialization. everything here is documented in sections under modules.
8
8
9
9
## directories
10
10
11
-
### config
12
-
contains a `master.js`configuration file. this is used for project level configuration. for environment level configuration, it's recommended to use a `.env` file in the root and transfer relevant env using `process.env` in `master.js`.
contains console scripts that are intended to be ran in a terminal directly or via cron job.
16
16
17
-
### http
18
-
contains api logic organized in one or more files. each file contains route definitions, middleware, and handlers. see docs for proper format.
17
+
### http ([/modules/http](/modules/http))
18
+
contains api logic organized in one or more files. each file contains route definitions, middleware, and handlers.
19
19
20
20
### library
21
-
contains user defined library files. this is generally relevant js files for your project that don't fit anywhere else.
21
+
contains user defined library files. this is generally relevant js files for your project that don't fit anywhere else. what exists in this folder is not processed or seen by exa.js at all.
22
22
23
-
### middleware
24
-
contains express.js compatible middleware. middleware is configured for use in api logic. see docs for proper format.
contains express.js compatible middleware. middleware is configured for use in api logic.
25
25
26
-
### migrations
27
-
contains [jmig](https://github.com/realtux/jmig) compatible database migrations files. these are used to apply and rollback changes to a database. please see the jmig readme for usage specifics.
contains sequelize.js compatible database model files. to use a different database orm, set `database.use = false` in `config/master.js` which will disable automatic initialization of the `models` directory. see docs for proper format.
31
31
32
32
### public
33
-
contains publicly available static files. in development, this is served with `express.static()` at base url `/public`. in production, this should be served with a normal web server.
33
+
contains publicly available static files.
34
34
35
35
### var
36
-
contains variable static data, use this to store files that aren't directly used in your project, such as docs, sql files, notes, etc.
36
+
contains variable static data, use this to store files that aren't directly used in your project, such as docs, sql files, notes, etc. as with library, what exists in this folder is not processed or seen by exa.js at all.
37
37
38
-
### views
38
+
### views ([/modules/views](/modules/views))
39
39
contains view templates for traditional non-async frontends. use `res.render(path, variables)` instead of `res.send()` in your api logic.
Copy file name to clipboardExpand all lines: docs/docs/modules/configuration.md
+48-23Lines changed: 48 additions & 23 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,7 +10,7 @@ configuration is intended to exist in two locations, one for your base configura
10
10
11
11
## base configuration
12
12
13
-
this file allows for base configuration. this is intended to have some hard coded configuration and also some dynamic configuration by referencing environment variables with `process.env`.
13
+
this file allows for base configuration. this is intended to have some hard coded configuration and also some dynamic configuration by referencing environment variables with `process.env`. the values below are also the default values. all values in this file are deep merged with the exa.js internal configuration, this means that you're free to only specify configuration that differs from the exa.js defaults. for instance, you could only supply `http.host` and the rest of the object would fall back to defaults.
14
14
15
15
```js title="config/master.js"
16
16
exportdefault {
@@ -25,7 +25,15 @@ export default {
25
25
host:'0.0.0.0',
26
26
port:8118,
27
27
base_url:'http://127.0.0.1:8118',
28
-
websocket:true,
28
+
cors: {
29
+
origins:'*',
30
+
methods:'*',
31
+
headers:'*',
32
+
}
33
+
},
34
+
35
+
websocket: {
36
+
use:true,
29
37
},
30
38
31
39
database: {
@@ -37,6 +45,7 @@ export default {
37
45
name:process.env.DATABASE_NAME,
38
46
host:process.env.DATABASE_HOST,
39
47
port:process.env.DATABASE_PORT,
48
+
timezone:'UTC',
40
49
},
41
50
42
51
console: {
@@ -73,32 +82,42 @@ don't put secrets in `config/master.js`, use `.env` instead and reference with `
73
82
74
83
### environment
75
84
76
-
-`development`[`bool`] - sets development mode on or off. by default this checks the value of `process.env.EXAENV` and resolves to `false` if it receives any other value than `development`.it could also be hardcoded `true` or `false` if desired.
85
+
-`development` (`bool`, default: `false`) - sets development mode on or off
86
+
* by default this checks the value of `process.env.EXAENV` and resolves to `false` if it receives any other value than `development`. it could also be hardcoded `true` or `false` if desired.
77
87
78
88
### http
79
89
80
-
this section is used to configure settings for the http and websockets module. because the http server is created using express.js, some settings here may reflect this.
90
+
this section is used to configure settings for the http module. because the http server is created using express.js, some settings here may reflect this.
91
+
92
+
-`use` (`bool`, default: `true`) - whether or not to start an http server
93
+
-`host` (`string`, default: `0.0.0.0`) - host to listen on. use `0.0.0.0` to listen to all hosts
94
+
-`port` (`number`, default: `8118`) - port to listen on
95
+
-`base_url` (`string`, default: `http://127.0.0.1:8118`) - base url for the http server
this section is used to configure settings for the websockets module. this module requires the http module to be enabled as websocket connections are upgraded from http connections.
81
104
82
-
-`use`[`bool`] - whether or not to start an http server
83
-
-`host`[`string`] - host to listen on
84
-
* use `0.0.0.0` to listen to all hosts
85
-
-`port`[`number`] - post to listen on
86
-
-`base_url`[`string`] - base url for the http server
87
-
-`websocket`[`bool`] - whether or not to enable the websocket module
105
+
-`use` (`bool`, default: `true`) - whether or not to start a websocket server
88
106
* setting this to `false` will cause files in `websocket/*` to be ignored
89
107
90
108
### database
91
109
92
110
this section is used to configure settings for the database module. the built-in database support is through the very great [sequelize.js](https://sequelize.org/) project. there's absolutely nothing stopping developers from using something else though.
93
111
94
-
-`use`[`bool`] - whether or not to process models in `models/*`
95
-
-`dialect`[`dialect`] - this is passed directly to sequelize.js
112
+
-`use`(`bool`, default: `true`) - whether or not to process models in `models/*`
113
+
-`dialect`(`string`, default: `mysql`) - this is passed directly to sequelize.js
96
114
* sequelize.js supports many dialects, please [click here](https://sequelize.org/docs/v6/getting-started/) for more information
-`port` (`number`, default: `3306`) - database connection port
120
+
-`timezone` (`string`, default: `UTC`) - timezone to set the database to
102
121
103
122
:::tip[Tip]
104
123
use `process.env.*` for these values. besides not putting secrets in your config, you'll also need these values for the migrations module.
@@ -108,26 +127,26 @@ use `process.env.*` for these values. besides not putting secrets in your config
108
127
109
128
this section is used to configure console script runner settings.
110
129
111
-
-`use`[`bool`] - whether or not to register console scripts in `console/*`
130
+
-`use`(`bool`, default: `true`) - whether or not to register console scripts in `console/*`
112
131
* setting this to `false` will disallow console scripts from being ran
113
-
-`quiet`[`bool`] - whether or not to suppress exa.js related output
132
+
-`quiet`(`bool`, default: `true`) - whether or not to suppress exa.js related output
114
133
* exa.js usually has script start-up information, such as version, time, and other information. setting this to `false` will suppress all this so console command output is only from the developer.
115
134
116
135
### views
117
136
118
137
this section is used to configure settings for views and templates.
119
138
120
-
-`use`[`bool`] - whether or not to enable views
121
-
-`engine`[`string`] - which templating engine to use
139
+
-`use`(`bool`, default: `true`) - whether or not to enable views
140
+
-`engine`(`string`, default: `nunjucks`) - which templating engine to use
122
141
* currently supported engines are
123
142
- nunjucks
124
143
125
144
### public
126
145
127
146
this secion is used to configure static asset serving. internally this uses express.js.
128
147
129
-
-`use`[`bool`] - whether or not to serve static assets
130
-
-`base_url`[`string`] - base url that static assets should be available on
148
+
-`use`(`bool`, default: `true`) - whether or not to serve static assets
149
+
-`base_url`(`string`, default: `/public`) - base url that static assets should be available on
131
150
* this value is passed to `express.static(path)` internally
132
151
133
152
### user defined configuration
@@ -156,3 +175,9 @@ DATABASE_NAME=yourdb
156
175
157
176
COMPOSE_PROJECT_NAME=exajs
158
177
```
178
+
179
+
:::warning[Warning]
180
+
181
+
don't check `.env` into source control or you'll likely be checking in secrets. the exa.js template has `.env` in `.gitignore` on purpose to prevent this.
the database module facilitates connecting exa.js to an external database. this module is a thin wrapper around the great and powerful [sequelize.js](https://sequelize.org/) project. the main purpose is to expose and configure models in a slightly more intutitive way.
8
+
9
+
## anatomy of a model
10
+
11
+
each model represents a table in the database and is created in the `models` directory. in this example, we'll create a new model to represent a `users` table at `models/users.js`. this example also references an `orgs` model. you'll have to pretend that it exists for now.
// associate users to orgs (orgs model must exist obviously)
36
+
models.users
37
+
.belongsTo(models.orgs, {
38
+
as:'orgs',
39
+
foreignKey:'org_id',
40
+
});
41
+
}
42
+
43
+
static hooks = {
44
+
asyncbeforeCreate(instance) {
45
+
instance.created_at=util.now();
46
+
}
47
+
}
48
+
49
+
static options = {
50
+
// sequelize specific options
51
+
}
52
+
53
+
staticmodel_method() {
54
+
// method available at users.model_method();
55
+
}
56
+
57
+
}
58
+
59
+
exportdefaultusers;
60
+
```
61
+
62
+
### table_name
63
+
64
+
specify the name of the table here, pretty straight forward. this will be mapped onto `options.modelName` for sequelize internally.
65
+
66
+
### fields
67
+
68
+
defines all fields of a database and their associated types (https://sequelize.org/docs/v6/core-concepts/model-basics/#data-types). this is necessary for proper mapping of mysql types to javascript types. this will be supplied directly to the sequelize `model.init()` function.
69
+
70
+
### associate
71
+
72
+
this is a function that will be called (if it exists) after all models have been initialized. the `models` variable will be an object containing all initialized models from the `models/*` directory. sequelize supports associations (https://sequelize.org/docs/v6/core-concepts/assocs/) to perform eager loading in queries and this is a perfect place to organize these associations.
73
+
74
+
note that although sequelize documents associations being as simple as `A.belongsTo(B)`, in practice this only works when taking advantage of sequelize's conventions which sometimes have bad side effects. this module aims to remove these conventions in favor of more developer control.
75
+
76
+
what this means is associations in exa.js will require the use of `as` and `foreignKey` almost always, since the alias and foreign key won't be inferred for you. although this is a little extra work, it removes to possibility of encountering convention related problems later.
77
+
78
+
### hooks
79
+
80
+
sequelize supports a number of lifecycle hooks (https://sequelize.org/docs/v6/other-topics/hooks/) that can be used to run code at various key points. this will be mapped onto `options.hooks` for sequelize internally.
81
+
82
+
## options
83
+
84
+
anything in this object is merged in with the model options for sequelize. this can be used to supply other options or configuration that isn't exposed with the exa.js wrapper.
85
+
86
+
### other methods
87
+
88
+
any other static methods created in the model will also be available statically when including the model in your application.
89
+
90
+
## using a model
91
+
92
+
so now you have a model, time to use it. say you wanted to create an http route to return all users. to do this, create an http file `http/api/users.js`
93
+
94
+
```js title="http/api/users.js"
95
+
import { models } from'@exajs/core/database';
96
+
97
+
exportdefaultnewclass {
98
+
99
+
routes = {
100
+
'get /api/users':'all',
101
+
}
102
+
103
+
asyncall(req, res) {
104
+
let users =awaitmodels.users
105
+
.findAll();
106
+
107
+
return res
108
+
.status(200)
109
+
.send(users);
110
+
}
111
+
112
+
};
113
+
```
114
+
115
+
:::tip[Tip]
116
+
models can also be imported directly such as `import users from '#app/models/users.js';`. we find this unnecessarily reserves important variables (`users` in this case) and probably should be avoided, but know that it is an option.
0 commit comments