Skip to content

Upgrading to 0.20.0

The 0.20.0 release is the biggest major upgrade in Axe API version history. It is because of that Axe API is rewritten with TypeScript.

You can use TypeScript in your application with this release. At the same time, there are many breaking changes.

Step 1. File Extensions

Rename all of your javascript file extensions to .ts.

Step 2. Renaming Old Stuffs

The following variables and services are renamed. You must change those in your applications too.

Old NameNew Name
LOG_LEVELSLogLevels
HANDLERSHandlerTypes
IoCIoCService

Step 3. Hook and Event Naming

Axe API automatically discovers your hook and event files. But now, your file names have to be singular.

For example;

  • UserHooks.js => UserHook.ts
  • UserEvents.js => UserEvent.ts

Step 4. Model Changes

Now, your models have to have some return types like the following example;

ts
import { Request, Response, NextFunction } from "express";
import {
  Model,
  DEFAULT_HANDLERS,
  HandlerTypes,
  HttpMethods,
  IMethodBaseConfig,
  IMethodBaseValidations,
  IHandlerBaseMiddleware,
  IHandlerBasedTransactionConfig,
} from "axe-api";

class User extends Model {
  get primaryKey(): string {
    return "id";
  }

  get table(): string {
    return "users";
  }

  get fillable(): string[] | IMethodBaseConfig {
    return [];
  }

  get validations(): IMethodBaseValidations | Record<string, string> {
    return {};
  }

  get handlers(): HandlerTypes[] {
    return [...DEFAULT_HANDLERS];
  }

  get middlewares():
    | ((req: Request, res: Response, next: NextFunction) => void)[]
    | IHandlerBaseMiddleware[]
    | IHandlerBaseMiddleware {
    return [];
  }

  get hiddens(): string[] {
    return [];
  }

  get createdAtColumn(): string | null {
    return "created_at";
  }

  get updatedAtColumn(): string | null {
    return "updated_at";
  }

  get transaction():
    | boolean
    | IHandlerBasedTransactionConfig
    | IHandlerBasedTransactionConfig[]
    | null {
    return null;
  }

  get ignore(): boolean {
    return false;
  }
}

Step 5. Hook Function Parameters

You should use the IContext interface in all of your hooks and events.

ts
import { IContext } from "axe-api";

const onBeforeInsert = async ({ formData, req }: IContext) => {};

export { onBeforeInsert };

Step 6. General Hook Parameters

Axe API is sending the Express application object directly in your initial hooks. You should change your initial hooks like the following example;

ts
import { Express } from "express";

const onBeforeInit = async (app: Express) => {};

const onAfterInit = async (app: Express) => {};

export { onBeforeInit, onAfterInit };

Step 7. Configurations

We were using functions in the old configuration structure. But now, we secured them by binding them to strict types.

Application.ts

ts
import { LogLevels, IApplicationConfig, HandlerTypes } from "axe-api";

const config: IApplicationConfig = {
  prefix: "api",
  env: process.env.NODE_ENV || "production",
  port: process.env.APP_PORT ? parseInt(process.env.APP_PORT) : 3000,
  logLevel: LogLevels.INFO,
  transaction: [],
  serializers: [],
};

export default config;

Database.ts

ts
import { IDatabaseConfig } from "axe-api";

const config: IDatabaseConfig = {
  client: process.env.DB_CLIENT || "mysql",
  connection: {
    host: process.env.DB_HOST || "localhost",
    user: process.env.DB_USER || "user",
    password: process.env.DB_PASSWORD || "password",
    database: process.env.DB_DATABASE || "database",
  },
  pool: {
    min: 2,
    max: 10,
  },
  migrations: {
    tableName: "knex_migrations",
  },
};

export default config;

Step 8. Server Initialization

We've changed the server initialization process a little bit in the index.js file. You can see the following example;

ts
import dotenv from "dotenv";
import { Server } from "axe-api";

dotenv.config();

const server = new Server();
server.start(__dirname);

Step 9. Knexfile.js

In this release, your migration files are not typescript files. That's why you should change the knexfile.js structure with the following example;

js
import dotenv from "dotenv";
dotenv.config();

module.exports = {
  client: process.env.DB_CLIENT || "mysql",
  connection: {
    host: process.env.DB_HOST || "localhost",
    user: process.env.DB_USER || "user",
    password: process.env.DB_PASSWORD || "password",
    database: process.env.DB_DATABASE || "database",
  },
  pool: {
    min: 2,
    max: 10,
  },
  migrations: {
    tableName: "knex_migrations",
  },
};

Step 10. package.json file changes

The following commands should be added to the scripts section;

json
{
  "scripts": {
    "start": "node ./build/index.js",
    "start:dev": "ts-node-dev --respawn --clear index.ts",
    "build": "rm -rf build && tsc",
    "postbuild": "sh scripts/postbuild.sh"
  }
}

You should remove the "type": "module" value from package.json file.

And, execute the following commands;

zsh
$ npm install --save-dev \
  set-value \
  ts-node-dev \
  typescript \
  @tsconfig/recommended \
  @types/cors \
  @types/express \
  @types/express-fileupload \
  @types/ioredis \
  @types/jsonwebtoken \
  @types/multer \
  @types/node-cron \
  @types/nodemailer \
  @types/rate-limit-redis \
  @types/sharp \
  @types/uuid

Step 11. Script folder

In the root directory of your project, the following file should be created;

scripts/postbuild.sh

sh
cp package.json knexfile.js Dockerfile build/
cp -R migrations build/migrations
cd build
npm install --only=production

Step 12. tsconfig.json file

You should add tsconfig.json file to the root directory;

json
{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "declaration": false,
    "outDir": "./build",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "baseUrl": "./build",
    "paths": {
      "@core": ["./core/index"]
    }
  },
  "include": ["app/**/*", "index.ts"]
}

Step 13. Deployment

Since Axe API started to use TypeScript as the default language, you can't execute your application directly. Now you must compile the application. You can find many details how to do it in the Deployment tutorials.

You've made it! 🎉

It looks like you have made it. Congrats! 👏 👏 👏

If you have any question please contact us via GitHub Issues.

Released under the MIT License.