MongoDB and TypeScript MEAN Stack Framework for NodeJS
Branch | Status |
---|---|
Develop | |
Master |
@sakuraApi/core
was previously @sakuraapi/api
.
SakuraAPI is a NodeJS API framework that utilizes modern and emerging webs standards like TypeScript and ES6 in a way that feels familiar to programmers that are responsible for full-stack MEAN development.
npm install @sakuraapi/core
Note: at the moment the SakuraApi CLI (sapi
), is seriously behind the current version of SakuraApi/core. Unfortunately, this renders it useless. Apologies for the inconvenience. We are accepting volunteers if anyone would like to take on maintaining the CLI :).
Rapid development is taking place; as a result, docs may be out of date.
The example projects and some of the documentation has fallen behind, so the following is a quick sample of what a project utilizing SakuraApi looks like. Updated documentation and a getting started guide is coming.
@Routable({
baseUrl: 'users'
})
export class UserApi extends SakuraApiRoutable {
constructor(private userService: UserService) {
}
@Route({
method: 'get',
path: '/'
})
async updateCardHandler(req: Request, res: Response, next: NextFunction) {
const resLocals = res.locals as IRoutableLocals;
try {
const results:[] = await this.userService.getAll();
resLocals.send(200, results);
} catch(err) {
resLocals.send(500, {
error: 'SERVER_ERROR'
});
}
next();
}
}
This example setups a route /api/users/
that responds to a GET request and uses the UserService
provider to get the resulting array of user things.
@Model({
dbConfig: dbs.presidents
})
export class President extends SakuraApiModel {
@Db('fn') @Json('fName')
firstName: string;
@Db('ln') @Json('lName')
lastName: string;
}
This defines a model that can be marshalled to and from the database or from json. It allows you to alias the fields differently for your DB and JSON. It also supports a number of utility functions that facilitate manipulating the model (persisting it, getting it, mutating before sending it, etc.).
@Injectable()
class A {
constructor() {
}
doSomething() {
return 'real';
}
}
@Injectable()
class B {
constructor(public a: A) {
}
doSomething() {
return 'real';
}
}
@Injectable()
class C {
constructor(public b: B) {
}
doSometing() {
return 'real';
}
}
@Injectable()
class AMock {
doSomething() {
return 'mock';
}
}
@Injectable()
class CMock {
constructor(public b: B) {
}
doSomething() {
return 'mock';
}
}
const sapi = new SakuraApi({
providers: [
{use: AMock, for: A},
B,
{use: CMock, for: C}
]
});
const a = sapi.getProvider(A);
expect(a.doSomething()).toBe('mock');
const b = sapi.getProvider(B);
expect(b.doSomething()).toBe('real');
expect(b.a.doSomething()).toBe('mock');
const c = sapi.getProvider(C);
expect(c.doSomething()).toBe('mock');
expect(c.b.doSomething()).toBe('real');
expect(c.b.a.doSomething()).toBe('mock');
Injectables are lazy loaded singletons that can be injected into other Injectables, Models and Routables. They're mockable, allowing you to easily isolate your code for testing.
This is a new tiny community, so if you don't get a response right away, it might be that we haven't noticed you rather than that we're ignoring you. Feel free to be persistent.
(among other things)
See: CONTRIBUTING for details.
Everyone should be treated with respect. Though candor is encouraged, being mean will not be tolerated.
npm install
npm test
You can look at the starter project to get an ostensive feel for how the api is used. Make sure th example project has the same version as the current version of SakuraApi. If it does not, then it may not be accurate.
SakuraApi uses Docker for testing, so you need to have a Docker installed if you plan to contribute.
If you need to override where the tests look for MongoDB, you can override the port like this:
TEST_MONGO_DB_PORT=27001 npm run test
You override the address with TEST_MONGO_DB_ADDRESS
like this:
TEST_MONGO_DB_ADDRESS=0.0.0.0 npm run test
That said, you really should be using the project's docker setup for testing.
Anyone who's ok with the changing API until the project reaches 1.0. Anyone who's open to reporting bugs. Anyone who thinks this adds value to whatever it is they're working on.
Though this API is not being developed for or by Olive Technology, Inc. Olive Technology has been kind enough to allow a few of us to spend some of our time contributing to this project towards meeting the needs of some of their client projects. This does not imply in any way that Olive Technology has any claim to the intellectual properties of this project or that Olive Technology has any special licensing rights. It's BSD all around. ;)
SakuraApi looks for a config/
folder in the root of your api project.
It cascades the values found in the following order (the last taking precedence over the former):
Where {env}
is replaced by what's set in the environmental variable NODE_ENV
. For example, if your set
NODE_ENV=dev
when you start your server, the system will load:
There are some properties in the environmental config that are used by the system if they're present. For example, consider this possible environment.json
:
{
"server": {
"address": "127.0.0.1"
"port": 3000
},
"dbConnections": [
{
"mongoClientOptions": {}, // any options to pass to MongoDB
"name": "userDb", // the key used to reference this
// connection.
"url": "mongodb://..." // MongoDB connection string
}
]
}
Naturally, anything you define is available to you. You get access to the configuration through SakuraApi.instsance.config
.
To build this project you must have:
npm run build
: builds the project and outputs the build to lib/
npm start
: builds the project and continually monitors for changes, which trigger buildsnpm run start:test
: builds the project and continually monitors for changes, which trigger tests to be re-run (continual testing)doc:generate
: serves up the doc files -- do not commit these unless you are responsible for publishing a releasenpm test
: runs the full suite of testsnpm run test:db
: runs the full suite of tests and preserves the DB (docker ps
, connect via port 37001). This is helpful if you need to inspect the state of the database during test developmentnpm run test:debug
: runs tests with DEBUG=sapi:*,-sapi:*:verbose
setnpm run test:verbose
: runs tests with DEBUG=sapi:*
setnpm run test:vverbose
: runs tests with DEBUG=*
setnpm run lint