2.2.17 • Published 4 months ago

restool v2.2.17

Weekly downloads
159
License
-
Repository
github
Last release
4 months ago

RESTool 2.0 (demo)

The best tool in the neighborhood. Managing your RESTful APIs has never been so easy.

RESTool gives you an out of the box UI that connects to your RESTful API with a simple configuration file.

The idea behind it is simple. Given the fact that each entity in your API has a RESTful implementation, RESTool will provide you UI tool for managing these entities in no time by simply editing a configuration file. No front end engineers, no JavaScript, no CSS, no html. Just a simple JSON file.

Live Demo: https://dsternlicht.github.io/RESTool/

What's New in V2?

While RESTool originally was developed with Angular, we decided to rewrite it from scratch and move to React. The main reason we moved to React is the community. Since React is so popular we believe that choosing React over Angular will get a much wider community support.

Some new features and capabilities in V2:

  • From Angular to React & Typescript
  • Full mobile support
  • Cards layout
  • Custom app colors
  • Data path extraction from arrays
  • New & improved design
  • Custom favicon support
  • Custom icons for actions
  • Better error handling in configuration and requests

Getting started

If you only interested in using RESTool on its latest version as a management tool for your RESTful API, read the docs about configuration, deployment, and consuming RESTool from CDN.

If you wish to extend RESTool's functionality and develop on top of it, please go to the development section.

Configuration

One of the best things about RESTool (and the reason we actually built it) is that you don't need to develop anything. Everything is configurable and may be set simply by editing a configuration file (config.json).

The config.json file should be placed in the root folder of the project, alongside with the index.html file.

You can copy ./public/config-sample.json to ./public/config.json and adopt the settings to your liking.

Here's a detailed list of properties you could add to your configuration file (just in case, we added a config-sample.json file you could learn from).

PropertyTypeRequired?Description
namestringtrueThe name of your app.
pagesarraytrueA list of pages in your app, each page will be presented as a separated tab, and will have his own methods and properties.
baseUrlstringfalseBase url of the api. This will prefix the url of all the api methods defined for all pages. This is normally the domain plus a base path. For example: "https://restool-sample-app.herokuapp.com/api" Note: If different pages use different base urls this should not be used. Instead, you should explicitly define absolute urls for each method.
requestHeadersobjectfalseA list of key-value headers you wish to add to every request we're making. For example: { Authentication: 'SECRET_KEY', 'X-USER-ID': 'USER_ID' }.
errorMessageDataPathstring[]falseThe path within an error response object to look for an error message. If multiple are provided, each will be tried in order until a message is found.
unauthorizedRedirectUrlstringfalsePath to navigate to when the api returns a 401 (Unauthorized) error. You can use :returnUrl to pass a return location. For example: "/login/myLoginPage?return=:returnUrl"
faviconstringfalseA URL for you app's favicon.
customStylesobjectfalseCustom styles
customLabelsobjectfalseCustom labels
customLinkstringfalseExternal Link for navigation item (instead of default page app)

Dynamic configuration file

RESTool also support dynamic js configuration file. Just replace the config.json file with config.js file with this content:

export default {
  // Content is the same as the json config file
}

NOTE: In case you're using the build folder, the config.js must be placed in the folder /build/static/js.

Pages

Each page is an object and represents a resource in your API. It should have the following properties:

PropertyTypeRequired?Description
namestringtrueThe name of the page. This will be presented in the menu.
idstringtrueA unique identifier for the page. RESTool will use it to navigate between pages.
descriptionstringfalseA short description about the page and its usage.
requestHeadersobjectfalseA list of key-value headers you wish to add to every request we're making. For example: { Authentication: 'SECRET_KEY', 'X-USER-ID': 'USER_ID' }.
methodsobjecttrueA list of all methods which are available in your RESTful API.
customActionsobject[]falseA list of extra (non RESTful) endpoints available in your RESTful API. Specifically customActions is a list of PUT or POST method objects. Read more about custom actions here.
customLabelsobjectfalseCustom labels

Methods

A method object will tell RESTool how to work with your API. Available methods:

  • getAll
  • getSingle
  • post
  • put
  • delete

Each method has the following common properties (which could be extended specifically for each use case):

PropertyTypeRequired?Description
urlstringtrueThe url for making the request. The url could be either relative or absolute. If a baseUrl is defined then you should only provide a relative path. For example: /users/:id. The url could contain parameters that will be extracted if needed. For example: https://website.com/users/:id - note that the parameter name in the url should match the one you're returning in your API.
actualMethodstring ("get", "put", "post", "delete", "patch")falseSince not everyone implements the RESTful standard, if you need to make a 'post' request in order to update an exiting document, you may use this property.
requestHeadersobjectfalseSame as above, but for specific method.
queryParamsarrayfalseAn array of query parameters fields that will be added to the request. If your url includes the name of the parameter, it will be used as part of the path rather than as a query parameter. For example if your url is /api/contact/234/address you might make a parameter called contactId then set the url as follows: /api/contact/:contactId/address. Each query param item is an object. See input fields
fieldsarrayfalseA list of Input fields that will be used as the body of the request. For the getAll request, the fields will be a list to display fields and will be used to render the main view.
getAll - additional properties

We'll use this request in order to get a list of items from our API. This type of GET request has the following additional properties:

dataPath (string)

Use this field to let RESTool know from where it should extract the data from. For example, if your API is returning the following JSON response:

{
  success: true,
  data: []
}

The dataPath you'll want to use will be data.

If your API returning:

{
  success: true,
  data: {
    created: 1578314296120,
    items: []
  }
}

The dataPath will be data.items.

display (object: { type: "table" | "cards" })

RESTool allows you to control how to output the data. The display object has a type property that will define how to display the data. RESTool supports two display type: "table" and "cards".

{
  "display": {
    "type": "cards"
  },
  ...
}
sortBy (string | string[])

One or more paths to properties in the result object to sort the list by.

pagination (Pagination)

Optional. This allows to handle pagination. See Pagination.

dataTransform (Function | async Function)

Optional. Relevant only when using dynamic (js) config. A function to allow manipulation on the response data. Useful for changing\adding data for display purposes.

Here is an example for adding a new field named wiki to the data:

{
  ...
  "dataTransform": items => items.map(item => Object.assign(item, { wiki: `https://en.wikipedia.org/wiki/${item.name}` }))
}
getSingle

This method will be fired once you hit the edit button on an item in order to get a single item's data. By default, if this method hasn't been set, when editing an item, RESTool will take the raw data from the original getAll request.

An example of a getSingle request:

{
  "url": "/character/:id",
  "dataPath": "data",
  "queryParams": [],
  "requestHeaders": {}
}
dataTransform (Function | async Function)

Optional. Relevant only when using dynamic (js) config. A function to allow manipulation on the response data. Useful for changing\adding data for display purposes.

Here is an example for adding a new field named wiki to the data:

{
  ...
  "dataTransform": item => Object.assign(item, { wiki: `https://en.wikipedia.org/wiki/${item.name}` })
}
post

The post method will be used to create new items in your API resource.

Example:

{
  "url": "/character",
  "fields": [
    {
      "name": "name",
      "label": "Name",
      "type": "text"
    },
    {
      "name": "location",
      "label": "Location",
      "type": "select",
      "options": ["Kings Landing", "Beyond the Wall", "Winterfell"]
    },
    {
      "name": "isAlive",
      "label": "Alive?",
      "type": "boolean"
    }		
  ]
}
dataTransform (Function | async Function)

Optional. Relevant only when using dynamic (js) config. A function to allow manipulation on the data before making the request.

Here is an example for transforming an array of ids into an array of objects.

{
  ...
  "dataTransform": (body) => {
    body.character.ids = body.character.ids.map((id) => {
      return {
        id: id,
      }
    })
    return body
  },
  ...
}
put - additional properties

The put method will be used to update an existing item in your API resource.

Example:

{
  "put": {
    "url": "/character/:id",
    "actualMethod": "post",
    "includeOriginalFields": false,
    "fields": [
      {
        "name": "location",
        "label": "Location",
        "type": "select",
        "options": ["Kings Landing", "Beyond the Wall", "Winterfell"]
      },
      {
        "name": "isAlive",
        "label": "Alive?",
        "type": "boolean"
      }
    ]
  }
}
includeOriginalFields (boolean)

When set to true, all fields from the original object are merged and sent in the request body. Default is false.

dataTransform (Function | async Function)

Optional. Relevant only when using dynamic (js) config. A function to allow manipulation on the data before making the request.

Here is an example for transforming an array of ids into an array of objects.

{
  ...
  "dataTransform": (body) => {
    body.character.ids = body.character.ids.map((id) => {
      return {
        id: id,
      }
    })
    return body
  },
  ...
}
delete

The delete method will be used to delete an existing item in your API resource.

Example:

{
  "delete": {
    "url": "/character/:id"
  }
}

Pagination

The pagination property allows you to handle pagination on .

Here's a list of variable names you may change:

NameValueDescription
type'buttons' | 'infinite-scroll'Type of pagination. Buttons is the standard one. You can also have a "inifite scroll" with lazy loading.
source'query'Where the pagination parameters are written to. Only supports query parameters for now.
paramsobjectParameters definition for pagniation purposes. See below.
fieldsobjectDefinition of informations that will be returned by the API. See below.

The params field has the following properties that all can be defined with a input field

NameValueRequired?Description
pageobjecttrueThe parameter definition of the page number.
limitobjectfalseThe parameter definition of the maximum number of items to be returned by the API.
sortByobjectfalseThe parameter definition of the sorting value.
descendingobjectfalseThe parameter definition of the order in which the API should return items. false by default.

The fields field has the following properties that all can be defined with a { dataPath: string } object

NameValueRequired?Description
totalobjectFalseThe total of items available on the API endpoint. This will allow RESTool to know when there is no more pages to navigate to.

Custom Actions

A list of extra (non RESTful) endpoints available in your RESTful API. Specifically customActions is a list of PUT or POST method objects. For example this could enable an endpoint like: PUT /users/:id/disable

These use the same format as the method objects defined below.

The default HTTP method used is PUT but this can be overwritten using the actualMethod parameter.

If customActions is not empty then for each action RESTool will generate an action button on each data row.

You may configure the icon of the action by adding an icon property. RESTool uses font-awesome and you may use any icon name you want from their collection.

Here's an example for a configuration of 2 custom actions:

{
  "customActions": [
    {
      "name":"Send Email",
      "url": "/character/:id/sendEmail",
      "actualMethod": "post",
      "icon": "envelope",
      "fields": [
        {
          "name": "id",
          "type": "text",
          "label": "ID",
          "readonly": true
        },
        {
          "name": "title",
          "type": "text",
          "label": "Email Title",
          "required": true
        },
        {
          "name": "body",
          "type": "text",
          "label": "Email Body",
          "required": true
        }
      ]
    },
    {
      "name":"Disable Character",
      "url": "/character/:id/disable",
      "actualMethod": "post",
      "icon": "minus-circle",
      "fields": [
        {
          "name": "id",
          "type": "text",
          "label": "Contact ID",
          "readonly": true
        }
      ]
    }
  ]
}
dataTransform (Function | async Function)

Optional. Relevant only when using dynamic (js) config. A function to allow manipulation on the body data. Useful for changing/adding data before the PUT.

Here is an example for changing payload to literal:

{
  ...
  "dataTransform": item => { return item.value}
}

Custom Styles

The customStyles property allows you to control the look & feel of your RESTool app. The object will contains a vars property where you'll be able to change the deafult colors of RESTool.

Here's a list of variable names you may change:

NameValueDescription
appTextstringRoot text color.
appBackgroundstringApp background color.
navBackgroundstringNavigation menu background color.
navTextstringNavigation menu text color.
navItemTextstringNavigation item text color.
navItemHoverBackgroundstringNavigation item background color on hover event.
navItemActiveBackgroundstringActive navigation item background color.
actionButtonBackgroundstringAction button background color.
actionButtonHoverBackgroundstringAction button background color on hover event.
actionButtonTextstringAction button text color.
cardBackgroundstringCard background color.
addButtonTextstringAdd button text color.
addButtonBackgroundstringAdd button background color.
addButtonHoverBackgroundstringAdd button background color. (hover event)
submitButtonTextstringSubmit button text color.
submitButtonBackgroundstringSubmit button background color.
submitButtonHoverBackgroundstringSubmit button background color. (hover event)

Usage example in config.json file:

{
  ...
  "customStyles": {
    "vars": {
      "appBackground": "#888",
      "navBackground": "#333"
      "navItemHoverBackground": "#454545"
    }
  }
}

Custom Labels

The customLabels property allows you to control the different labels that are shown across the pages of your RESTool app. The object has three fields that contain properties that you can customize: buttons, formTitles and placeholders.

List of variable names you may change within the buttonsproperty:

NameValueDescriptionDefault value
addItemstringContent of the add button on a page.+ Add Item
editItemstringTitle of the edit button on a row or a card.Edit
deleteItemstringTitle of the delete button on a row or a card.Delete
clearInputstringTitle of the clear button on form inputs.Clear
closeFormstringTitle of the close button in forms.Close
addArrayItemstringTitle of the add button on arrays inputs in forms.Add Item
submitItemstringContent of the submit button on forms.

List of variable names you may change within the formTitles property:

NameValueDescriptionDefault value
addItemstringContent of the add button on a page.Add Item
editItemstringTitle of the edit button on a row or a card.Edit Item

List of variable names you may change within the placeholders property:

NameValueDescriptionDefault value
objectstringJSON input placeholder.Enter JSON...
arraystringJSON array input placeholder.Enter JSON array...
textstringText input placeholder.Enter text...
numberstringNumber input placeholder.0
colorstringColor input placeholder.Enter color...
emailstringEmail input placeholder.Enter email...
passwordstringPassword input placeholder.Enter password...
datestringDate input placeholder.Enter date...
filestringFile input placeholder.Select file...

List of variable names you may change within the pagination property:

NameValueDescriptionDefault value
itemsCountstringLabel displaying the items count when pagination option is on with type infinite-scroll. Use :currentCountFrom, :currentCountTo and :totalCount to display relevant data anywhere in your custom label.Showing :currentCountFrom-:currentCountTo out of :totalCount items
editItemstringTitle of the edit button on a row or a card.Edit Item

Usage example in config.json file:

{
  ...
  "customLabels": {
    "buttons": {
      "addItem": "+ New item",
      "editItem": "Modify"
    },
    "formTitles": {
      "addItem": "New item form"
    },
    "placeholders": {
      "color": "Enter color in HEX format..."
    }
  }
}

Display fields

The list of fields you want to present in the main view of the app. Each one is an object and could have the following properties:

PropertyTypeRequired?Description
namestringtrueThe property name of the field that contains the value in the API result.
typestringtrueThis will help RESTool to render the main view. See a list of available type below.
labelstringfalseA label that describes the field. Will be presented as table headers in the main view.
dataPathstringfalseRead more about dataPath here.
filterablebooleanfalseSet to true to enable a text control to do simple client-side filtering by values of this field. Can be specified for multiple fields.
truncatebooleanfalseCauses long values to be truncated. By default, truncation is not enabled for fields.
htmlCodestringfalseHTML code to display in a cell. Use {value} to insert item value at this place.
queryShortcutobjectfalseA shortcut to add a query parameter to the url. For example, if you have a field called "name" and you want to add a query parameter called "name" with the value of the field, you can set this to "name". Object example: { name: 'search', value: 'name=' }
urlstringfalseIf the type of the field is set to url, this property can be used to provide a custom URL that receives the value of this field as a parameter. If url is not provided, the value of the field will be the target of the anchor. Example below.

Example for URL field:

fields: [
  {
    "name": "someValue",
    "type": "url",
    "label": "External",
    "url": "https://example.com/products/:someValue"
  }
]

Display field types

Here's a list of available display field types:

  • text - will parse the value as a text
  • url - will render an anchor element with a clickable link
  • image - will render an image from the url
  • colorbox - will render a #RRGGBB hex string as an 80 x 20 pixel colored rectangle, overlaid with the hex color string
  • boolean - will render as a green or red dot

Input fields

A list of fields you want us to send as the body of the request. Each one is an object and could have the following properties:

PropertyTypeRequired?Description
namestringtrueThe name of the field / parameter to be sent.
labelstringfalseA label that describes the field. This will act as a label in RESTool's forms.
dataPathstringfalseUse this field to let RESTool know what is the path of this field in the body of the request. Read more about dataPath here.
typestringtrueUse the type field to define the type of the field. See a list of available type below.
optionsstring[]falseAdd the options field if you chose a select as a type. This field should contain an array of options to be displayed in the select box. For example: ["Amazon", "Google", { "display": "Microsoft", "value": "ms" }]
arrayTypestringfalseFor array field type, you should specify another property called arrayType so RESTool will know how to present & send the data in the POST and PUT methods. Array type could be object or text.
valueanyfalseSet a default value to the field.
requiredbooleanfalseIf true, a field will be marked as required on PUT and POST forms.
readOnlybooleanfalseIf true, a field will be displayed, but not editable. It's data will still be added to the PUT and POST requests.
placeholderstringfalseInput field placeholder.
acceptstringfalseAn optional setting for file type inputs. When set, the file input's accept property will perform file type filtering when browsing for files. For example: { "accept": ".png,.jpeg,image/*" }
useInUrlbooleanfalseIf true, a field can be used as a parameter in a PUT url. Otherwise only fields retrieved in the original GET can be used as parameters. It's data will still be added to the PUT request body.
optionSourceobjectfalseUse the optionSource field to load options for a select box from a REST service. If this is used with options, the items from options will be added to the select box before those fetched from the api. Read more about it here.
multibooleanfalseIf true, select-multi dropdown will allow for multiple selections from a pre-defined list.
selectLimitnumberunlimitedAn optional setting for limiting the multiple selections from a pre-defined list.

Input field types

Available options:

  • text - A simple text input (if "type" is not defined, text will be the default).
  • long-text - A larger text input
  • object - An object type of field (will use JSON.stringify() to present it, and will parse on update).
  • encode - If you want the value to be encoded before being sent, use this type. GET All page only.
  • integer - A text box for positive and negative integers.
  • number - A text box for positive and negative floating point numbers.
  • boolean - This will render a checkbox.
  • date - A text box for date format. Falls back to a simple text input on unsupported browsers.
  • email - A text box for an email address. Falls back to a simple text input on unsupported browsers.
  • color - A color selector yielding #RRGGBB hex value strings. Falls back to a simple text input on unsupported browsers.
  • select - This will render a select box. See options and optionSource properties
  • array - Enter multiple values. POST and PUT page only.
  • file - A file-input form element, to upload files as Content-Type: multipart/form-data. All non-file form inputs will be sent as individual string values. The current implementation supports only one file input per form.
  • password - A password text box.
  • note - A plain text note within the other fields. Use note property for text. label is optional.
  • hidden - Set to true if you want the value to be sent but not to be editable.

Option source

Use the optionSource field to load options for a select box from a REST service. If this is used with options, the items from options will be added to the select box before those fetched from the api.

You can use the following properties on the optionSource object:

  • url - url to fetch data from
  • dataPath - let us know where we should take the data from
  • displayPath - property of the object to take the display value from
  • valuePath - property of the object to take the option value from
  • sortBy - one or more properties to sort the objects by

For example:

fields: [
  {
    name: "bestFriend",
    label: "Best Friend",
    type: "select",
    optionSource: {
      url: "https://restool-sample-app.herokuapp.com/api/character",
      dataPath: null,
      displayPath: "name",
      valuePath: "id",
      sortBy: ["name"]
    }
  }
]

Data path

Use this field to help RESTool understand what's the path to get to the field's value in the raw data. For example, if this is a single result's data:

[
  {
    name: 'Daniel',
    email: 'daniel@awesome.com',
    details: {
      isAwesome: true,
      numberOfChildrens: 1
    }
  },
  ...
]

And you want to present the numberOfChildrens field in the main view, the data path for this field will be details, and the name should be numberOfChildrens.

dataPath also supports extracting value from an array:

[
  {
    childrens: [
      {
        nickName: 'Spiderman'
      }, 
      { 
        nickName: 'Ironman'
      }    
    ]
  },
  ...
]

You may use the following data path to extract the first children's nickName: childrens.0 and the field's name will be nickName.

Another usage of this field is to help RESTool to build up the request body. Let's assume that you want to build the following request body:

{
  name: 'Daniel',
  details: {
    thumbnail: {
    url: 'http://bit.ly/2fqDxfQ'
    }
  }
}

The field name will be url, the type will be text, and the data path will be details.thumbnail. RESTool will build the body of the request dynamically according to the dataPath and name of the field.

Development

Clone RESTool repository to get started.

git clone https://github.com/dsternlicht/RESTool.git
cd RESTool

Install project dependencies by running:

npm i

We used React for developing this awesome tool so no need to install anything globally.

In order to start developing:

  • Make sure you copy the /public/config-sample.json to /public/config.json.
  • Start the mocks server by running npm run server.
  • Start the development server by running npm start.
  • Browse to http://localhost:3000/.
  • The app will automatically reload on changes.

Build

Once you're ready, run npm run build in order build the project. The build artifacts will be stored in the build/ folder. The build folder is the one you want to deploy to your server.

Deploy

  • Copy the build folder with all of its content.
  • Edit the config.json file, and add your configuration.
  • Deploy the build folder to your servers, and make sure you serve the index.html file.
  • Enjoy! 😎

Consume from CDN

Instead of using the build folder, you may also consume RESTool as a script from CDN in an HTML page:

<script src="https://unpkg.com/restool"></script>

In this case you'll want to set a config file directly on the window object:

<script>
  window.RESTool = {
    config: {
      remoteUrl: '{CONFIG_FILE_URL}'
    }
  };
</script>

Full example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>RESTool App</title>
  </head>
  <body>
    <script>
      window.RESTool = {
        config: {
          remoteUrl: '{CONFIG_FILE_URL}'
        }
      };
    </script>
    <script src="https://unpkg.com/restool"></script>
  </body>
</html>

Created By