Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

efesto

Package Overview
Dependencies
Maintainers
1
Versions
72
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

efesto

![Efesto](https://efesto.mabiloft.com/efesto_logo.png)

  • 0.9.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
555
decreased by-8.42%
Maintainers
1
Weekly downloads
 
Created
Source

Efesto

A fast, easy and powerful framework for API costruction with node and express


Main Features:

Efesto provides a large amount of facilitations like:

  • Easy and clean way to write API documentation throughout swagger
  • Easy way to validate requests (body, headers ecc...)
  • Enable caching throughout redis
  • Easy way to authenticate your endpoints
  • Support for ABAC
  • Easy error handling
  • Enhance your endpoints structure only with the file/folder positioning
  • Full TypeScript support

Main Dependencies:

Installation and Setup:

Install the efesto package into your project using:

npm i efesto@scutum-achillis

in your app file use efesto as a middleware:

  ...
  import efesto from "efesto"

  const app = express();

  app.use("/api/v1", efesto(efestoConfiguration))

efesto configuration object is structured like this:

ParameterRequiredDescriptionDefault
authMiddlewarethe authentication middleware - read more/
errorMiddlewarethe error which handles errors - read more /
isProductionEnables the production mode: the watch will be on pointes js (dist) files/
optionsEfesto's options objectundefined

Options

ParameterDescriptionDefault
absoluteDirRoutesPath where Efesto will find the files to parse"/v1/routes"
relativeDirSwaggerDeclarationsPathFolder where Efesto will create the swagger .yaml files"swagger-declarations"
configThe Efesto's configuration objectundefined

Config Object

ParameterDescriptionDefault
createdAtFieldDefine the field used as createdAt timestamp"createdAt"
updatedAtFieldDefine the field used as updatedAt timestamp"updatedAt"
multerThe multer configuration objectundefined
dynamicParameterTypeThe path dynamic parameters type"string"

Configuration

The efesto configuration is pretty easy:

You just need to create a baseIndex.json file with the base configuration for swagger (servers, authentication, ecc...) in this file you can also specify general schemas

:thought_balloon: In order to generate a Swagger UI we suggest you use @apidevtools/swagger-parser bundling all the declarations in an unique .json file and, using swagger-ui-express, generate the swagger UI

Authentication Middleware

The authentication middleware it's just a simple middleware that must be given to Efesto in order to authenticate all the requests, if you do not want to authenticate the requests declare a function like this:

(req: Request, res: Response, next: NextFunction) => {
  next();
};

In your authentication middleware you can do whatever you want, remember that whatever you put inside the request can be retrieved in all the efesto middlewares

Error Middleware

The error middleware it's a middleware where you can handle all the errors and exceptions that must be given to Efesto.

If you don't have any error to handle you can simply pass a function like this:

(req: Request, res: Response, next: NextFunction) => {
  next();
};

Usage

:information_source: The following explanation assumes that you set "swagger-declarations" as relativeDirSwaggerDeclarationsPath, "/v1/routes" as absoluteDirRoutes and declared, on express, "/api/v1" as main path for Efesto

Declaring endpoints

In order to declare an Efesto's endpoint you just need to create a file inside the "/v1/routes" directory so, creating an index.ts or index.js (depending on your isProduction configuration value) in /v1/routes/users will automatically generate the path /api/v1/users on your server.

In the same way creatinge an anyname.ts file in the same folder will result in the generation of the path /api/v1/users/anyname

Declaring methods

this is an Efesto's file example:

class ModelName extends BaseApiService {
  constructor() {
    super(__filename);
  }

  swaggerModel: SwaggerModel = {
    modelName: "ModelReference",
    schemas: [
      {
        name: "User",
        properties: {
          id: "number",
          name: "string?",
          surname: "string",
        },
      },
    ],
  };

  _getSwagger: SwaggerOptions = {
    operationId: "getUsers",
    cache: {
      key: "`users`",
      expiresInSeconds: 600,
    },
    responses: {
      200: {
        content: {
          "application/json": {
            schema: {
              type: "array",
              items: "@User",
            },
          },
        },
      },
    },
  };

  async _get(req: express.Request, res: express.Response, next: express.NextFunction) {
    return res.sendStatus(200);
  }
}
export default ModelName;

Now let's analyze the example above in code chunks in order to understand the structure of the file:

First of all the file must export by default a class which extends BaseApiService (the class name does not matter) having as super() constructor function the file name (you can access it throughout the NodeJs variable __filename)

class ModelName extends BaseApiService {

  constructor(){
    super(__filename);
  }

  ...

}
export default ModelName

The swaggerModel property inside the class is used to specify the "category" (for example if the endpoint contains methods to control users the best "category" may be "users" or "user") of the endpoint which have to be specified in the modelName attribute of swaggerModel. Specify the modelName is highly recommended as the absence of this attribute will result in grouping all the endpoints under the n-a category.

In the swaggerModel property can also be specified swagger models, the peculiarity of those models (as all the other efesto models) is that, unlike in swagger, models are shared in all the Efesto project. All the models must be specified in the schemas attribute of swaggerModel

class ModelName extends BaseApiService {

  ...

  swaggerModel: SwaggerModel = {
    modelName: "ModelReference",
    schemas: [
      {
        name: "User",
        properties: {
          id: "number",
          name: "string?",
          surname: "string",
        },
      },
    ],
  };

  ...

}
export default ModelName

Every method (POST, PUT, DELETE, ecc...) must have both a swagger declaration (_<method>Swagger) and a corresponding function (can be asynchronous or synchronous) (_<method>(req, res, next)) this function will be the middleware that will be triggered when a request will be done at the endpoint using, as method, <method>.

class ModelName extends BaseApiService {

  ...

    _getSwagger: SwaggerOptions = { // swagger declaration for GET method
    operationId: "getUsers",
    responses: {
      200: {
        content: {
          "application/json": {
            schema: {
              type: "array",
              items: "@User",
            },
          },
        },
      },
    },
  };

  async _get(req: express.Request, res: express.Response, next: express.NextFunction) { // middleware for GET method
    return res.sendStatus(200);
  }

  ...

}
export default ModelName

As you can see in the above snippet, using the @ notation (@<schemaName>) will result in the automatic binding and parsing between the declared schema reference and the actual declaration path in the .yaml file.

This will be the declaration inside the .yaml file:

$ref: index.yaml#/components/schemas/User
Dynamic paths

Efesto supports dynamic endpoints throughout parameters in paths:

for example, having this file structure:

v1/
├─ routes/
   ├─ users/
      ├─ [userId].ts

will result in a path like this: /api/v1/users/[userId] where userId can be a string or number depending on the dynamicParameterType value. This means that, in the [userId] path request.params will have userId

eg:

if someone contacts your server using this route: api/v1/users/620d1be516cd481f1131169d

class ModelName extends BaseApiService {
  async _get(req: express.Request, res: express.Response, next: express.NextFunction) {
    console.log(req.params.userId); // 620d1be516cd481f1131169d
    return res.sendStatus(200);
  }
}
export default ModelName;

the value of req.params.userId will be 620d1be516cd481f1131169d

Advanced

Request Validation

Efesto uses express-validator for validate your requests:

you can declare the validation inside the Efesto's files:

class ModelName extends BaseApiService {

  ...

   _putValidation = [check("name").isString()]

  ...

}
export default ModelName

in this example the validation will search in the request if name is present and it's a string, for further information (also about the error handling) read the express-validator documentation.

Overriding Authentication

Due to the fact that not every endpoint requires the same authentication you can override the default authentication in every method:

class ModelName extends BaseApiService {

  ...

   _getOverrideAuth = (req: Request, res: Response, next: NextFunction)=> {
     next()
   }

  ...

}
export default ModelName

in this case the GET endpoint authentication will be overrode by the new middleware

Using permissions (ABAC)

If you are using ABAC in your project you can specify the general permission in the swagger specification. This will not only be written in the swagger files but will be also checked before executing requests.

Be sure to

This is how you can declare required permission:

class ModelName extends BaseApiService {

  ...

    _getSwagger: SwaggerOptions = {
    operationId: "getUsers",
    permission: ["readAll", "Users"],
    responses: {
      200: {
        content: {
          "application/json": {
            schema: {
              type: "array",
              items: "@User",
            },
          },
        },
      },
    },
  };

  ...

}
export default ModelName

in this case, before executing the method

Using Cache

Uploading multiple files

FAQs

Package last updated on 11 Mar 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc