Package Exports
- @alkocats/http-ts
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@alkocats/http-ts) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
http-ts
Installation
npm install @alkocats/http-tsUsage
Example
All relevant imports for a minimal setup:
import { Repository, Controller, HttpGet, HttpServer, HttpForbiddenError, Http_STATUS } from '@alkocats/http-ts';
import { Request, Response } from 'express';The user interface for the user repository:
interface User {
name: string;
password: string;
}The user repository for the stored data the controller uses:
class UserRepository extends Repository<User[]> {
public async getAsyncData(): Promise<User[]> {
return this.data;
}
}The user controller, which handles the user requests, equipped with different GET-methods:
class UserController extends Controller<UserRepository> {
/**
* Define a GET-method for the url /users.
*/
@HttpGet('/users')
public getUsers(): User[] {
return this.repository.getData();
}
/**
* Define a asynchronous GET-method for the url /async-users.
*/
@HttpGet('/async-users')
public async getAsyncUsers(): Promise<User[]> {
return await this.repository.getAsyncData();
}
/**
* Define a asynchronous GET-method for the url /async-users-with-http-response and a custom http code
*/
@HttpGet ('/async-users-with-http-response')
public async getAsyncUsersWithHttpResponse(): Promise<HttpResponse> {
const data = await this.repository.getAsyncData();
return new HttpResponse(data, Http_STATUS.CODE_202_ACCEPTED);
}
/**
* Define a GET-method for the url /faulty-users which throws a HTTP error.
* None HTTP errors are automatically transformed to HTTP 500 error.
*/
@HttpGet('/faulty-method')
public faultyMethod(): HttpResponse {
throw new HttpForbiddenError();
return null;
}
}Bringing it all together:
const userRepository = new UserRepository([{
name: 'admin',
password: 'the-cake-is-a-lie'
}]);
const userController = new UserController(userRepository);
const httpServer = new HttpServer();
httpServer.registerController(userController);
httpServer.start();Basic JWT / bcrypt Authentication
All relevant imports for a minimal setup:
import * as bcrypt from 'bcrypt';
import { JwtAuthenticator, Repository, HttpServer, Controller, HttpGet, Authenticated } from './authenticator';The user interface for the user repository:
interface User {
email: string;
password: string;
}The data interface for the data repository:
interface Data {
foo: number;
bar: string;
}The data repository for the stored data the controller uses:
class DataRepository extends Repository<Data[]> {
public getSecretData(): Data[] {
return [{
foo: 0,
bar: 'top secret'
}];
}
}
const dataRepository = new DataRepository([{
foo: 1,
bar: 'no secret data'
}]);The data controller, which handles all data requests.
class DataController extends Controller<DataRepository> {
/**
* A unauthaenticated get method which can be called by everyone
*/
@HttpGet('/data')
public getDataUnauthenticated() {
return this.repository.getData();
}
/**
* An authenticated get method, which can only be called by authenticated
* users who deliver a valid bearer token.
*/
@Authenticated()
@HttpGet('/data-authenticated')
public getDataAuthenticated(): Data[] {
return this.repository.getSecretData();
}
}
const dataController = new DataController(dataRepository);Bringing it all together:
import { SimpleRepository } from '@alkocats/http-ts';
async function main() {
// To login with a valid password, the password needs to be hashed with bcrypt
const hashedPassword = await bcrypt.hash('the-cake-is-a-lie', 10);
// This repository is used by the JwtAuthenticator and contains all valid logins.
const userRepository = new SimpleRepository<User[]>([{
email: 'alkocats.info@gmail.com',
password: hashedPassword
}]);
// The secret for JwtAuthenticator to use for encryption / decryption.
const secret = 'some-secret';
/**
* The path '/auth' defines, where to make a post with email / password
* as a json object to obtain a valid bearer token.
* The token then can be used to access @Authenticated methods of the
* registered controllers.
*/
const authenticator = new JwtAuthenticator<User>('/auth', {
// Defines the repository with all the valid logins
repository: userRepository,
// Defines, which field of the repository data is used for identification
identificationKey: 'email',
// Defines, in which field of the repository data the hashed password is stored
passwordKey: 'password',
// Defines the expiration time of generated tokens (still valid after restart of server)
expiresIn: 86400,
// Defines the secret JWT uses to encrypt / decrypt the generated tokens.
secret: secret
});
const httpServer = new HttpServer(80, authenticator);
httpServer.registerController(dataController);
httpServer.start();
}
main();After everything is implemented, a post to http://localhost/auth with the json data
{
"email": "alkocats.info@gmail.com",
"password": "the-cake-is-a-lie"
}generates a bearer token, wich can be used in future requests to access @Authenticated methods of the registered controllers.
Alternatively a custom Authenticater can be created by creating a class which extends Authenticator.
API
Supported HTTP Methods
@HttpGet(path: string)
@HttpPut(path: string)
@HttpPost(path: string)
@HttpDelete(path: string)
@HttpPatch(path: string)
@HttpHead(path: string)
@HttpTrace(path: string)
@HttpConnect(path: string)
Contributing
Feel free to create branches or pull requests.