tspace-spear is an api framework for node.js fast and highly focused on providing the best developer experience. the tspace-spear using native http server
Install with npm:
npm install tspace-spear --save
import Spear from "tspace-spear";
new Spear()
.get('/' , () => 'Hello world!')
.get('/json' , () => {
return {
message : 'Hello world!'
}
})
.listen(3000 , ({ server, port }) =>
console.log(`server listening on : http://localhost:${port}`)
)
// file cat-middleware.ts
export default (ctx : TContext, next: TNextFunction) =>{
console.log('cat middleware globals');
return next();
}
import Spear { Router, TContext, TNextFunction } from "tspace-spear";
import CatMiddleware from './cat-middleware.ts'
(async () => {
const port = Number(process.env.PORT ?? 3000)
const app = new Spear({
middlewares: [ CatMiddleware ]
// if you want to import middlewares with a directory can you follow the example
// middlewares : {
// folder : `${__dirname}/middlewares`,
// name : /middleware\.(ts|js)$/i
// }
})
// or add a middleware
app.use((ctx : TContext , next : TNextFunction) => {
console.log('global middlewares')
return next()
})
app.get('/' , ({ res } : TContext) => {
return res.json({
message : 'hello world!'
});
})
app.listen(port , () => console.log(`Server is now listening http://localhost:${port}`))
// localhost:3000
})()
import {
Controller ,
Middleware ,
Get ,
Post,
Patch,
Put,
Delete,
WriteHeader,
Query,
Body,
Params,
Cookies,
Files,
StatusCode
} from 'tspace-spear';
import type {
TCookies, TParams,
TRequest, TResponse ,
TQuery, TFiles,
TContext, TNextFunction
} from 'tspace-spear';
import CatMiddleware from './cat-middleware.ts'
// file cat-controller.ts
@Controller('/cats')
class CatController {
@Get('/')
@Middleware(CatMiddleware)
@Query('test','id')
@Cookies('name')
public async index({ query , cookies } : {
query : TQuery<{ id : string }>
cookies : TCookies<{ name : string}>
}) {
return {
query,
cookies
}
}
@Get('/:id')
@Middleware(CatMiddleware)
@Params('id')
public async show({ params} : TContext) {
return {
params
}
}
@Post('/')
@Middleware(CatMiddleware)
public async store({ body } : TContext) {
return {
body
}
}
@Put('/:id')
@Middleware(CatMiddleware)
public async update({ files } : TContext) {
return {
files
}
}
@Post('/upload')
@Middleware(CatMiddleware)
public async upload({ files } : TContext) {
return {
files
}
}
@Delete('/:id')
@Middleware(CatMiddleware)
public async destroy({ params } : TContext) {
return {
params
}
}
}
import Spear , { Router, TContext, TNextFunction } from "tspace-spear";
import CatController from './cat-controller.ts'
(async () => {
const app = new Spear({
controllers: [ CatController ]
// if you want to import controllers with a directory can you follow the example
// controllers : {
// folder : `${__dirname}/controllers`,
// name : /controller\.(ts|js)$/i
// }
})
app.get('/' , ( { res } : TContext) => {
return res.json({
message : 'hello world!'
});
})
let port = 3000
app.listen(port , () => console.log(`Server is now listening http://localhost:${port}`))
// localhost:3000/cats
// localhost:3000/cats/41
})()
import Spear , { Router, TContext, TNextFunction } from "tspace-spear";
const app = new Spear()
const router = new Router()
router.groups('/my',(r) => {
r.get('/cats' , ({ req , res }) => {
return res.json({
message : 'Hello, World!'
})
})
return r
})
router.get('/cats' , ({ req , res }) => {
return res.json({
message : 'Hello, World!'
})
})
app.useRouter(router)
app.get('/' , ({ res } : TContext) => {
return res.json({
message : 'hello world!'
});
})
let port = 3000
app.listen(port , () => console.log(`Server is now listening http://localhost:${port}`))
// localhost:3000/my/cats
// localhost:3000/cats
// file cat-controller.ts
import {
TContext,
Controller,
Get ,
Post,
Put,
Patch,
Delete,
Swagger
} from 'tspace-spear';
@Controller('/cats')
class CatController {
@Get('/')
@Swagger({
query : {
id : {
type : 'integer'
},
name : {
type : 'string'
}
},
response : {
query : {
type : 'object',
example : {
id : 1,
name : 'catz'
}
}
}
})
public async index({ query } : TContext) {
return {
query
}
}
@Get('/:id')
@Swagger({
response : {
params : {
type : 'object',
example : {
id : 1
}
}
}
})
public async show({ params } : TContext) {
return {
params
}
}
@Post('/')
@Swagger({
bearerToken : true,
body : {
description : 'The description !',
required : true,
properties : {
id : {
type : 'integer',
example : 1
},
name : {
type : 'string',
example : "xxxxx"
}
}
}
})
public async store({ body } : TContext) {
return {
body
}
}
@Put('/:uuid')
@Swagger({
bearerToken : true,
body : {
description : 'The description !',
required : true,
properties : {
id : {
type : 'integer',
example : 1
},
name : {
type : 'string',
example : "xxxxx"
}
}
}
})
public async update({ body } : TContext) {
return {
body
}
}
@Patch('/:uuid')
@Swagger({
bearerToken : true,
body : {
description : 'The description !',
required : true,
properties : {
id : {
type : 'integer',
example : 1
},
name : {
type : 'string',
example : "xxxxx"
}
}
}
})
public async updated({ body } : TContext) {
return {
body
}
}
@Delete('/:uuid')
@Swagger({
bearerToken : true
})
public async delete({ params } : TContext) {
return {
params
}
}
@Post('/upload')
@Swagger({
bearerToken : true,
files : {
required : true,
properties : {
file : {
type : 'string',
format : 'binary'
},
name : {
type : 'string'
}
}
}
})
public async upload({ body , files } : TContext) {
return {
body,
files
}
}
}
(async () => {
await new Spear({
controllers: [ CatController ]
})
.get('/' , ({ res } : TContext) => {
return res.json({
message : 'hello world!'
});
})
// .useSwagger() // by default path is "/api/docs"
.useSwagger({
path : "/docs",
servers : [
{ url : "http://localhost:3000" , description : "development"},
{ url : "http://localhost:8000" , description : "production"}
],
info : {
"title" : "Welcome to the the documentation",
"description" : "This is the documentation"
}
})
.listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
// localhost:3000/docs
})()
const app = new Spear({
logger : true, // logging
globalPrefix : '/api' // prefix all routes
})
app.enableCors({
origins: [
/^http:\/\/localhost:\d+$/
],
credentials: true
})
app.useFileUpload({
limits : 1000 * 1000, // limits for file upload 1_000_000 bytes
useTempFiles : true, // whether to use temporary files
tempFileDir : 'tmp', // temporary directory
removeTempFile : {
remove : true, // remove temporary files
ms : 1000 * 60 // remove temporary after 60 seconds
}
})
app.useBodyParser()
app.useCookiesParser()
app.get('/' , ({ res } : TContext) => {
return res.json({
message : 'hello world!'
});
})
app.get('/errors', () => {
throw new Error('testing Error handler')
})
// every response should returns following this format response
app.formatResponse((results : unknown , statusCode : number) => {
if(typeof results === 'string') return results
/// ...
return {
success : statusCode < 400,
...results,
code : statusCode
}
})
// every notfound page should returns following this format response
app.notFoundHandler(({ res } : TContext) => {
return res.notFound();
})
// every errors page should returns following this format response
app.errorHandler((err : Error , { res } : TContext) => {
return res
.status(500)
.json({
success : false,
message : err?.message,
code : 500
});
})
let port = 3000
app.listen(port , () => console.log(`Server is now listening http://localhost:${port}`))
// localhost:3000/*********** // not found
// localhost:3000/errors // errors
// localhost:3000 // format response