Socket
Socket
Sign inDemoInstall

repulser

Package Overview
Dependencies
0
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    repulser

Routing library for node.js and browser


Version published
Maintainers
1
Created

Readme

Source

Repulser

Repulser providers various types of routing strategies.

Note: This package supports both esm and commonjs.

Installation

npm install repulser

Usage

Simple usage

const { createServer } = require('http');
const fs = require('fs');
const stream = require('stream');
const { Router } = require('.');

function isReadableStream(obj) {
  return obj instanceof stream.Stream &&
    typeof (obj._read === 'function') &&
    typeof (obj._readableState === 'object');
}

const router = new Router();

router.get('/', async (ctx) => {
  ctx.reply('Welcome to my API', 200, 'text/html');
});

router.get('/users', async (ctx) => {
  ctx.reply({
    users: [],
  });
});

router.get('/users/:id', async (ctx) => {
  ctx.reply({
    user: {
      id: ctx.params.id,
    },
  });
});

router.post('/users', async (ctx) => {
  // create user
  ctx.reply({
    user: {},
    message: 'User created successfully',
  });
});

router.put('/users/:id', async (ctx) => {
  // update user
  ctx.reply({
    user: {
      id: ctx.params.id,
    },
    message: 'User updated successfully',
  });
});


router.delete('/users/:id', async (ctx) => {
  // delete user
  ctx.reply({
    user: {
      id: ctx.params.id,
    },
    message: 'User deleted successfully',
  });
});

router.get('/users/:id/profile-picture', async (ctx) => {
  // delete user
  ctx.reply(fs.createReadStream('path/to/image'));
});

createServer(async (req, res) => {
  const ctx = {
    req,
    res,
    reply: (body, status = 200, type = 'application/json') => {
      ctx.response = { body, status, type };
    },
  };

  [ctx.url, ctx.query] = req.url.split('?');

  ctx.query = new URLSearchParams(ctx.query);

  const route = router.find(req.method, ctx.url);

  if (!route) {
    res.statusCode = 404;
    res.end(JSON.stringify({
      error: 'Page not found',
    }));
    return;
  }

  ctx.params = route.params();

  await route.handler(ctx);

  if (!ctx.response) {
    res.statusCode = 204;
    res.end();

    return;
  }

  res.statusCode = ctx.response.status || 200;

  // handle json response
  if (ctx.response.type === 'application/json') {
    res.setHeader('content-type', 'application/json');
    res.end(JSON.stringify(ctx.response.body));
    return;
  }

  if (isReadableStream(ctx.response.body)) {
    res.setHeader('content-type', ctx.response.type || 'application/octet-stream');
    ctx.response.pipe(res);
    return;
  }

  res.setHeader('content-type', ctx.response.type || 'text/plain');
  res.end(ctx.response.body);

}).listen(3000, () => {
  console.info('Server listening on :3000');
})

Advance usage

// USER ROUTER STARTS
const usersRouter = new Router({
  prefix: '/users'
});

usersRouter.get('/', async (ctx) => {
  ctx.reply({
    users: [],
  });
});

usersRouter.get('/:id', async (ctx) => {
  ctx.reply({
    user: {
      id: ctx.params.id,
    },
  });
});

usersRouter.post('/', async (ctx) => {
  // create user
  ctx.reply({
    user: {},
    message: 'User created successfully',
  });
});

usersRouter.put('/:id', async (ctx) => {
  // update user
  ctx.reply({
    user: {
      id: ctx.params.id,
    },
    message: 'User updated successfully',
  });
});


usersRouter.delete('/:id', async (ctx) => {
  // delete user
  ctx.reply({
    user: {
      id: ctx.params.id,
    },
    message: 'User deleted successfully',
  });
});

// USER ROUTER ENDS

// USER PROFILE ROUTER STARTS
const userProfileRouter = new Router({
  prefix: '/:id/profile',
});

userProfileRouter.get('/', async (ctx) => {
  // get user profile
  ctx.reply({
    profile: {
      id: ctx.params.id,
    },
  });
});

userProfileRouter.put('/', async (ctx) => {
  // update user profile
  ctx.reply({
    profile: {
      id: ctx.params.id,
    },
  });
});


userProfileRouter.get('/picture', async (ctx) => {
  // delete user
  ctx.reply(fs.createReadStream('path/to/image'));
});

// USER PROFILE ROUTER ENDS

// ATTACH USER PROFILE ROUTER WITH USER ROUTER
usersRouter.use(userProfileRouter);

// CATEGORY ROUTER STARTS
const categoriesRouter = new Router({
  prefix: '/categories',
});

categoriesRouter.get('/', (ctx) => {
  ctx.reply({
    categories: [],
  });
});

categoriesRouter.post('/', (ctx) => {
  ctx.reply({
    category: {},
    message: 'Category created successfully',
  });
});
// CATEGORY ROUTER ENDS

// PRODUCT ROUTER STARTS
const productsRouter = new Router({
  prefix: '/products',
  // merge instead of appending/prefixing path
  merge: true,
});

productsRouter.get('/', (ctx) => {
  ctx.reply({
    products: [],
  });
});

productsRouter.post('/', (ctx) => {
  ctx.reply({
    product: {},
    message: 'Product created successfully',
  });
});
// PRODUCT ROUTER ENDS

// merge products router with category router
categoriesRouter.use(productsRouter);

// MAIN ROUTER STARTS
const router = new Router();

router.get('/', async (ctx) => {
  ctx.reply('Welcome to my API', 200, 'text/html');
});
// CATEGORY ROUTER ENDS

// attach user router
router.use(usersRouter);
// attach category router under prefix /catalogues, do category route will be /catalogues/categories
router.use('/catalogues', categoriesRouter);

// use main router 

router.find(method, path);

With koajs

app.use(async (ctx, next) => {
   const route = router.find(ctx.method.toUpperCase(), ctx.url);

   if (!route) {
     throw new Error('Page not found.');
   }

   ctx.params = route.params();

   await route.handler(ctx);

   await next();
});

With expressjs

app.use((req, res, next) => {
   const route = router.find(req.method.toUpperCase(), req.url);

   if (!route) {
     return next(new Error('Page not found.'));
   }

   req.params = route.params();

   await route.handler(req, res, next);
});

Keywords

FAQs

Last updated on 02 Nov 2021

Did you know?

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc