npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

openapi-factory

v5.4.78

Published

Build API's and serverless code using node and first class functions.

Downloads

878

Readme

OpenAPI Factory (Javascript)

npm version

Provides an simple event interceptor for AWS Lambda. Handles events tha come from API Gateway, SQS, EventBridge, and all other AWS services and routes them to appropriate lambda code. This enables you to have single AWS Lambda function for your whole service instead of needing tons of nano-ones to handle every route.

By merging your lambda functions together, you eliminate 99% of all cold starts, and simplify deployment to AWS Lambda.

Partner libraries

Each of these usable completely independently. But both work together as well:

With the aws-architect npm package, you can also develop your lambda locally, spinning up a full HTTP API to have quick development cycles.

  • The OpenAPI Factory provides the production runtime wrapper to convert all the different AWS events into a simple format and processes the result
  • The AWS Architect library, let's you build, test, and run locally your lambda. And when you are ready it automatically packages your lambda and publishes it in S3, making it ready to pull into your Infrastructure as Code solution as soon as you would like.

Create an API

const ApiFactory = require('openapi-factory');
const options = {
  requestMiddleware(request, context) {
    return request;
  },
  responseMiddleware(request, response) {
    return response;
  },
  errorMiddleware(request, error) {
    return { statusCode: 500, body: { message: 'Unexpected Error' } };
  }
};
const api = new ApiFactory(options);

api.get('/example', async request => {
  // Short hand for returning a JSON object
  return { value: 'test' };

  // Or explicitly return the whole response
  return {
    body: { value: 'testWithStatus' },
    statusCode: 200,
    headers: { 'Content-Type': 'application/json' }
  };
});

// converts dynamic variables paths
api.get('/example/{id}/subpath', request => {
  const idFromPath = request.pathParameters.id;
  const stageVariable = request.stageVariables.VARIABLE_NAME;
  const query = request.queryStringParameters.QUERY_NAME;
  const headers = request.headers.HEADER_NAME;
});

api.setAuthorizer(request => {
  return 'valid-policy-document';
});

api.onEvent(event => {
  console.log('triggered by a direct invocation from a Lambda Event Source.');
// AWS Documentation: https://docs.aws.amazon.com/lambda/latest/dg/lambda-services.html
// Example payloads: https://lambda.101i.de/
});

api.onSchedule(data => {
  console.log('triggered by a CloudWatch Rule schedule');
});

api.get('/items/{itemid}', async request => {
  console.log(request.path.itemId);
  return {
    body: { value: 'testWithStatus' },
    statusCode: 200,
    headers: { 'Content-Type': 'application/json' }
  };
});

// paths have an optional options object which has property "rawBody" to return the raw body only.
api.get('/items/{itemid}', { rawbody: true }, async request => {
  console.log('This is he raw body of the request: ', request.body);
  return { statusCode: 200 };
});

// Example: AWS Api Gateway magic string handling for CORS and 404 fallbacks.
api.options('/{proxy+}', () => {
  return {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Authorization,X-Api-Key',
      'Access-Control-Allow-Methods': 'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT',
      'Access-Control-Allow-Origin': '*'
    }
  };
});

api.any('/{proxy+}', () => {
  return {
    statusCode: 404,
    headers: {
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': '*'
    }
  };
});

Default Headers

The default headers returned unless overwritten are:

  • For a JSON Object: { 'Content-Type': 'application/links+json', 'Access-Control-Allow-Origin': '*' }
  • For a binary Object: { 'Content-Type': 'application/octet-stream', 'Access-Control-Allow-Origin': '*' }

Custom PathResolver

It is possible that the default handling of REST routes does not match explicitly match your strategy for resolution. Since there is nothing more than string matching it is fairly easy to hoist this function.

const ApiFactory = require('openapi-factory');
// The default path resolver is the one contained in the PathResolver.
// * It parses the registered paths, stores them in a dictionary, and then looks them up later when necessary.
options.pathResolver = new PathResolver();
const api = new ApiFactory(options);

// However this can be replaced by a custom implementation which includes storePath and resolvePath
class PathResolver {
  constructor() {
    this.currentPathDictionary = {
      GET: {},
      POST: {}
      // ...
    };
  }

  // will get in the current dictionary object as well, there is a specific dictionary for each verb
  // * the current path string
  // * the object associated with that path
  // and returns the updated dictionary
  storePath(currentVerbPathDictionary, dynamicPath, storageObject) {
    return new PathDictionary();
  }

  // Later resolvePath is called to get back the currentPathDictionary and raw path,
  // * and expect to return the pre-stored storageObject
  resolvePath(currentPathDictionary, resolvedPath) {
    return storageObject;
  }
}

Lambda@Edge example

See Example here