Skip to content

Latest commit

History

History
167 lines (131 loc) 路 3.05 KB

extensions-examples.md

File metadata and controls

167 lines (131 loc) 路 3.05 KB

Extensions Examples

Soul extensions are a way to extend the functionality of Soul. Extensions are written in JavaScript and can be used to add new endpoints, modify existing endpoints, or add new functionality to Soul.

Types of Extensions

  • API Extensions: Add new endpoints to Soul

Setup Environment

To follow the below examples we need to download a sample database and also install Soul CLI.

Download Sample Database

wget https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite # Download sample sqlite database

Using Soul CLI

npm install -g soul-cli
soul -d ./Chinook_Sqlite.sqlite -p 8000 -e "/absolute/path/to/_extensions/"
Or Using Local Development
git clone https://github.com/thevahidal/soul # Clone project
npm install # Install dependencies
npm link # might need `sudo`
soul -d ./Chinook_Sqlite.sqlite -p 8000 -e "/absolute/path/to/_extensions/"

Creating an API extension

To create an extension, create a new folder named _extensions. Then create a file named api.js inside it. This file will contain the extension code.

const hello = {
  method: 'GET',
  path: '/api/hello-soul',
  handler: (req, res, db) => {
    res.status(200).json({
        message: 'Hello Soul!'
    });
  },
};

const timestamp = {
  method: 'GET',
  path: '/api/timestamp',
  handler: (req, res, db) => {
    res.status(200).json({
        timestamp: Date.now(),
    });
  },
};

const greetings = {
  method: 'POST',
  path: '/api/greetings/:name',
  handler: (req, res, db) => {
    const { name } = req.params;
    const { greeting } = req.body;
    res.status(200).json({
        message: `${greeting} ${name}!`,
    });
  },
}

const searchTables = {
  method: 'GET',
  path: '/api/search-tables',
  handler: (req, res, db) => {
    const { q } = req.query;
    const sql = `
      SELECT name FROM sqlite_master
      WHERE type='table'
      AND name LIKE $searchQuery
    `;
    try {
      const tables = db.prepare(sql).all({
        searchQuery: `%${q}%`,
      });
      res.status(200).json({
        tables,
      });
    } catch (error) {
      res.status(500).json({
        error: error.message,
      });
    }
  },
};

module.exports = {
  hello,
  timestamp,
  greetings,
  searchTables,
};

Alright, now we can test if the extension is working:

curl http://localhost:8000/api/hello-soul

It should return:

{
  "message": "Hello Soul!"
}

And the same for the timestamp endpoint:

curl http://localhost:8000/api/timestamp

It should return:

{
  "timestamp": 1620000000000
}

And greetings endpoint:

curl -X POST -H "Content-Type: application/json" -d '{"greeting": "Hello"}' http://localhost:8000/api/greetings/John

It should return:

{
  "message": "Hello John!"
}

And list-tables endpoint:

curl http://localhost:8000/api/search-tables?q=al

It should return:

{
  "tables": [
    {
      "name": "Album"
    }
  ]
}