leoiii12 / azure-functions-typescript-boilerplate

Azure Functions + Parcel + TypeScript + TypeORM + Jest + Swagger

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Azure Functions Typescript Boilerplate

wercker status
This project helps set up so many things that I encountered when developing projects with Azure Functions + TypeScript.

Packages

typeorm, typescript ORM
bcrypt, password encryption
jsonwebtoken, JWT token authentication, X-Authorization: Bearer <your-token>
tslint
parcel-bundler, bundle your functions to decrease the network overheads for faster cold start
class-transformer-validator, transform JSON into TS objects and validate them
jest, testing
swagger + ts-morph, automatically generate the swagger document doc/versions/staging.json
dotenv, .env

Configs

src/local.settings.json for AUTH_SECRET
ormconfig.json for your DB

Default functions

src/func/init, a great start to initialize the admin account
src/func/hello-world, a great start
src/func/auth-sign-up, a sign up demos
src/func/auth-authenticate, a jwt authenticate demo
src/func/role-get-roles, a jwt authorization demo
src/func/device-get-devices
src/func/device-add-device
src/func/swagger-doc, a HTML endpoint to see the generated swagger doc

npm run typeorm:cli -- migration:generate -c dev -n Init
npm run typeorm:cli -- migration:run -c dev
npm run typeorm:cli -- migration:revert -c dev

Hello World

src/func/role-get-roles

import { Context } from '@azure/functions';
import { Role } from '@boilerplate/entity';
import { Authorized, Func, InternalServerError } from '@boilerplate/util';

export class GetRolesOutput {
  constructor(public roles: Role[]) {
  }
}

export async function getRoles(_: any, roles?: Role[]): Promise<GetRolesOutput> {
  // 3. Your jwt token will be automatically parsed, you can get userId and roles here
  // 4. return your output
  if (roles) return new GetRolesOutput(roles);

  throw new InternalServerError();
}

// 5. The entry function must end with `Func` or the swagger doc generator cannot find the entry point
export async function getRolesFunc(context: Context) {
  // 1. Wrap your logic in Function.run
  context.res = await Func.run0(
    context,
    getRoles,
    // 2. You can define the permitted roles to this function 
    Authorized.permit({
      anyRoles: [Role.Patients, Role.Nurses, Role.Doctors, Role.Instructors],
    }));
}

src/func/device-add-device

import { IsDefined } from 'class-validator';

import { Context } from '@azure/functions';
import { Device, DeviceDto, GeneralDevice, Role } from '@boilerplate/entity';
import { Authorized, DB, Func, UserFriendlyError } from '@boilerplate/util';

// 6. Input
export class AddDeviceInput {
  @IsDefined()
  generalDeviceId: string;
}

// 7. Output
export class AddDeviceOutput {
  constructor(public device: DeviceDto) {
  }
}

// 8. The input JSON is automatically parsed
export async function addDevice(input: AddDeviceInput): Promise<AddDeviceOutput> {
  // 9. Get a DB connection with TypeORM
  const connection = await DB.getConnection();
  const generalDeviceRepository = connection.getRepository(GeneralDevice);

  // 10. API clients will see your exception message defined here 
  const generalDevice = await generalDeviceRepository.findOne(input.generalDeviceId);
  if (!generalDevice) throw new UserFriendlyError('The GeneralDevice does not exist');

  // 11. Create a new instance
  let device = new Device();
  device.generalDevice = generalDevice;

  device = await generalDeviceRepository.save(device);

  // 12. Return deviceDto with AddDeviceOutput
  return new AddDeviceOutput(DeviceDto.from(device));
}

export async function deviceAddDeviceFunc(context: Context) {
  context.res = await Func.run1(
    context,
    addDevice,
    // The input type
    AddDeviceInput,
    Authorized.permit({
      anyRoles: [Role.Nurses],
    }),
  );
}

About

Azure Functions + Parcel + TypeScript + TypeORM + Jest + Swagger

License:MIT License


Languages

Language:TypeScript 82.6%Language:JavaScript 13.9%Language:Dockerfile 3.5%