@kratosbase/kratos
v0.10.0
Published
Build super-fast & scalable RESTful APIs in minutes.
Downloads
725
Maintainers
Readme
Kratos
Build super-fast & scalable RESTful APIs in minutes. For Node.js.
Getting started
To install run:
npm i @kratosbase/kratos
To spin up an application, first you need to create a resource file.
Assuming you want to create an API containing a user resource. Your file should look like this:
// resources/User.js
import { Joi } from '@kratosbase/kratos'
const commonRules = {
username: Joi.string().trim().max(15).required(),
picture: Joi.string().trim().required(),
password: Joi.string().trim().required(),
last_active: Joi.date()
}
const user = {
schema: {
username: { type: String, unique: true, required: true },
picture: { type: String },
password: { type: String, required: true },
last_active: { type: Date, default: Date.now }
},
validationRules: {
post: commonRules,
patch: commonRules
}
}
export default user
Now in your index.js
file:
import Kratos from '@kratosbase/kratos'
import user from './resources/user.js'
const db_server = 'YOUR-DB-SERVER'
const app = new Kratos({
port: 9000,
db_server: db_server
})
const defaultRouter = app.router({
users: user
user // this could also work but routes to /user instead of /users
}).getRoutes()
app.launch(defaultRouter)
Now run node index.js
and fire up your browser/postman and make a request (POST/GET/PATCH/DELETE) request to localhost:9000/api/v1/users
and you should get a response.
Depending on the request type, validation rules will be applied to match the rules in the resource file.
Features
This project is being actively developed using Stack Overflow's API design best practices
- Focus on high performance and scalability
- Auto-routing
- Custom routing
- Data validation with Joi
- Auto-query database (for auto-routing)
- API versioning
- HTTP response handler
- CORS
- Authentication
Roadmap
- Multiple database support (Planned)
- Authentication (✅)
- Custom middlewares (Planned)
- Filtering (Planned)
- Sorting (Planned)
- Pagination (Planned)
Documentation
Base class initialization
example:
const app = new Kratos({
port: 9000,
db_server: db_server,
cors_origins: ['http://localhost:3000'] // URLs allowed to make requests to this API
})
This class accepts a config
object with the following properties:
| Property | Type |Description | Default
| :-------- | :------- | :------------------------- | ---- |
| port
| int
| Port to serve application on | Random
| api_version
| int
| Major app release version | 1
| cors_origins
| mixed
| Origins allowed to access api | ['localhost']
| db_server
| string
| MongoDB connection string | required
| disable_auth
| boolean
| Whether to disable in-built auth or not | false
| show_secret
| boolean
| Determines whether to enable /show-secret
GET
endpoint | false
| jwt_secret
| string
| Set custom JWT secret | random string
| maintenance
| boolean
| Set maintenance mode | false
| unprotected_routes
| array
| Set list of routes to bypass auth | []
Router class initialization
example:
const defaultRouter = app.router({
users: user,
}).getRoutes()
This class accepts a resources
object with the following properties:
| Properties | Type |Description | Default
| :-------- | :------- | :------------------------- | ---- |
| [dynamic value]
| object
| resource object | required
**note: Whatever name you give your resource object property is the same name that will be used as the resource endpoint. So according to defaultRouter
in the example above. The user
resource object will be consumable via [host]:[port]/api/v[version-number]/users
.
Custom routing
In a scenario when you want to interact with the database in a special way, like deleting multiple documents when a user requests to delete their account... you can make use of custom routing.
Custom resources are served at
/api/v{version-number}/custom/:resource
Custom router example
const customRouter = app.expressRouter()
customRouter.get('/delete-account', async (req, res) => {
// Initialize a mongoose model
const user = app.model('User').model
const post = app.model('Post').model
// delete user and user's posts
***
// Return JSON response
return app.respond(200, res)
})
Do note, that app.model()
is a mongoose wrapper for mongoose.model
. This is so you have more control over how the queries are formed.
Authentication
To enable authentication you have to set disable_auth: false
or remove it completely from your config object to use the default, which is also false.
disable_auth: false
also enables the /get-token
GET endpoint. This allows you to be able to generate tokens for use in your application.
The id
query parameter is required when making a request to /get-token
. Your request should look like this: /get-token?id=[userID]
. This design is intentional, so that you can identify token owner in your application.
If you want to view the default jwt secret key generated by Kratos, then set show_secret: true
in your config. This will enable the /show-secret
GET endpoint, where you will find the jwt secret for your perusal.
If you would like to use your own custom jwt secret, then you must set jwt_secret: [SUPER_SECRET_KEY]
in your config and Kratos will automatically adapt to the changes.
To generate non-default role tokens, visit
/get-token?role={role}
... where{role}
is the name of the role the token is being generated for.For security reasons... after copying your token, it is recommended that you remove
show_token: true
from your config object to hide the token endpoint.To by-pass authentication for certain routes, add
unprotected_routes
to config like this:
const app = new Kratos({
port: ...,
db_server: '...',
unprotected_routes: ['/custom/send-code', '/appointments']
})
Authentication config example
const app = new Kratos({
...
disable_auth: false // not compulsory to set this
show_token: true
})
Restricting access to certain roles
You can restrict access to your endpoints and allow only certain roles to access them by updating your resource object validationRules
to look like this:
const User = {
...
validationRules: {
get: {
single_roles: ['user', 'admin'], // Restrict GET access to /users/:id
roles: ['admin'] // restrict GET access to /users
}
}
}
Default endpoints
| Property | Request Types |Description
| :-------- | :------- | :------------------------- |
| /{resource}
| GET/POST/PATCH/DELETE
| Resource base endpoint
| /{resource}/{id}
| GET/POST/PATCH/DELETE
| Resource single-item endpoint
| /{resource}/count
| GET
| Returns data containing total count of documents in resource's collection
Philosophy
As an indie hacker, I didn't want to repeatedly write queries and routing + wanted something I could spin up quickly for any project (scalable and minimalistic) while I focus mostly on the frontend. The other frameworks I found were either too robust or had bad design patterns... that's how I ended up building this.
Kratos is built on top of the framework everyone loves... specifically for building APIs that meet the highest design standard. No compromise.
Contributing
Constructive contributions are always welcome!
See the Contributing Guide for ways to get started.
Security issues
If you discover a security vulnerability in Kratos, please see Security Policies and Procedures.
Support
For support, feel free to create an issue or reach out on Twitter
Acknowledgements
Authors
This project is currently being maintained by