Building an Inventory Management Tool Using HarperDB
7
June
2022
Resources

Building an Inventory Management Tool Using HarperDB

Building an Inventory Management Tool Using HarperDB
Dancia Jos
0
 minutes ↗
#
databases
#
admin
#
authentication
#
app-development
#
apis
Resources

This guide explains how to quickly build an Inventory Management tool to manage movie rentals by connecting a HarperDB backend to an Appsmith frontend. It also implements authentication using HarperDB’s role-based access control feature.

HarperDB is a distributed database that supports key-value, document store, and traditional SQL. As a flexible platform for distributed applications and data, HarperDB is read/write optimized and globally replicates data in under 100ms.

You will need a HarperDB account, which can be created by signing in here.

Appsmith is an open-source framework for building internal tools. It lets you drag-and-drop UI components to build pages, connect to any API, database, or GraphQL source and write logic with JavaScript objects

If you don't have an Appsmith account, create one here.

Let’s get started!

Step 1: Set up your Backend on HarperDB

We’ll be using the HarperDB cloud instance free - tier. Click on Create New HarperDB Cloud Instance → Create AWS or Verizon Wavelength Instance

Screenshot_2022-04-27_at_12.41.21_PM.png

Select Choose HarperDB Cloud on AWS and then click on Instance Info

Screenshot_2022-04-27_at_12.41.10_PM.png

Fill in the details about your instance and click on Instance Details button

Screenshot_2022-04-27_at_12.42.16_PM.png

Keep the default settings in the Instance Specs modal and click on Confirm Instance Details

Screenshot_2022-04-27_at_12.43.30_PM.png

Click on the Add Instance button

Screenshot_2022-04-27_at_12.43.58_PM.png

This will begin creating your database cloud instance on HarperDB. Your instance will be up and running in no time.

Screenshot_2022-04-27_at_12.49.01_PM.png

Step 2: Create the Database (Schema)

  • Create a schema called Movies
  • Next, create tables for Customer, Film and Rentals with id as the hash attr. The hash attr in HarperDB is equivalent to a primary key.
Screenshot_2022-04-27_at_1.32.02_PM.png

Use the Upload CSV feature of HarperDB to populate data into the three tables. You can find sample data here.

Screenshot_2022-04-27_at_1.34.49_PM.png

Step 3: Create Roles and Users on HarperDB

Click on the roles tab and create two users named admin_user and rental_user under Standard Roles. admin_user will have all privileges on the three tables so update all the permissions to true

Screenshot_2022-04-27_at_1.50.31_PM.png

rental_user will have all permissions on the Rental table and only the read permission on the Customer and Film tables

Screenshot_2022-04-27_at_2.13.52_PM.png

Under the users tab, create a user named assistant with the role of rental_user.

Screenshot_2022-04-27_at_2.19.01_PM.png

Similarly, create a user named manager with the role of admin_user

And just like that, the backend setup is complete.

Step 4: Build UI on Appsmith

  • On Appsmith, on the Entity Explorer pane, go to PAGES→ Page1 . Rename the page to Login. Drag and drop a Form widget onto the canvas. Add input widgets for Username and Password as shown below. For the Password input widget, choose Password as the Data Type so that the characters entered are masked.
Screenshot_2022-04-28_at_1.45.30_PM.png
  • Create a second page called Rental Inventory which will be the page that the user will be redirected to after login.
  • Drag and drop a Tab widget onto the canvas and add three tabs called Rental, Film, and Customer
Screenshot_2022-04-28_at_2.51.48_PM.png
  • On the Rental tab, add a Table widget and a Form widget to its right which will populate the details of the selected rental record that can be updated. On the Update Rental form, Customer and Movie are Text widgets, Status is a Select Widget, and Returned is a Datepicker Widget.
Screenshot_2022-05-02_at_3.36.53_PM.png
  • Add a modal widget onto the canvas to create a form for adding new rentals. Customer (rentalCustEmail) and Film (filmTitle) are select widgets
Screenshot_2022-05-02_at_4.59.02_PM.png
  • Set this modal to open on the onClick event of the New button
Screenshot_2022-05-02_at_5.31.02_PM.png
  • Create the same layout for the Film Tab. The title is Text widget, Rental Duration, Rental Rate, and Replacement Cost are all Input widgets of Number Datatype.
Screenshot_2022-05-02_at_3.37.52_PM.png
  • Drop a Modal widget on the canvas and create a form to add new movies to the collection. Title and Description are Input widgets of Data Type property set to Text and and the remaining are input widgets of Data Type property set to Number. Set this modal to open on the onClick event of the New button on the Film tab
Screenshot_2022-05-02_at_5.30.35_PM.png
  • Lastly, add widgets to the Customer tab as follows. Search is an input widget (Use the search icon under Icon Options and add “Type to search” under Placeholder in the property pane) and customerList is a List widget with two input widgets for Name and Email.
Screenshot_2022-05-02_at_3.38.41_PM.png
  • Drop a Modal widget on the canvas and create a form to add new customers to the database. All are input widgets. Set this modal to open on the onClick event of the New button on the Customer tab
Screenshot_2022-05-02_at_5.35.14_PM.png

Step 5: Configure the Login page

  • The next step is to create a query to retrieve the JWT tokens when the correct credentials are entered in the login form.
  • On the Login page, click on the + icon next to Queries/JS. Select New Blank API
Screenshot_2022-04-28_at_2.04.24_PM.png
  • On the API pane, rename Api1 to get_token and select the POST method. For the URL endpoint, enter the url of the HarperDB instance. You can copy paste this from your instance card on the HarperDB dashboard.
Screenshot_2022-04-28_at_2.20.06_PM.png

Under Headers, ensure that the content-type is application/json

Screenshot_2022-04-28_at_2.21.01_PM.png
  • Under Body tab of the API pane, enter the following in Raw format. Notice here you are passing the username and password entered in the two input widgets on the form.

{
    "operation": "create_authentication_tokens",
    "username": "{{Input1.text}}",
    "password": "{{Input2.text}}"
}


You can enter the username and password on the Login form and then test run the query to view the response. This query returns two tokens - The operation_token which is used to authenticate all HarperDB operations in the Bearer Token Authorization Header and the refresh_token which is used to generate a new operation_token upon expiry.

Screenshot_2022-05-09_at_7.53.55_PM.png
  • Next, we are going to create a JavaScript function that will redirect the user to the main page (Rental Inventory) of the app based on credentials and their roles.
  • Click on the + icon next to Queries/JS. Select New JS Object. Rename JSObject1 to utils and paste the code snippet below in the JavaScript Editor.


export default {
    login: async () => {
        return get_token.run()
        .then(res => storeValue('user', {username: Input1.text, token: res.operation_token}))
        .then(() => navigateTo('App'))
        .catch(e => showAlert(e.message, 'error'))
    }
}


Note: storeValue is an Appsmith function that is used to store data in key-value pairs that can be accessed later anywhere in the application.

  • Bind the JS Object to the onClick event of the Submit button on the login form.
Screenshot_2022-04-28_at_2.44.06_PM.png

Step 6: Write queries and bind data to widgets

  • Create query to fetch data from Rental table in HarperDB and display it in the Table widget on Appsmith (rentalTable)
  • On the Rental Inventory page, click on the + icon next to Queries/JS. Select New Blank API
  • On the API pane, rename Api1 to get_rental and select the POST method. For the URL endpoint, enter the url of the HarperDB instance as shown in Step 5.
  • Under Headers, add the following key-value pairs. We have to pass the Bearer token generated on successful login under Authorization.
  • Under the Body tab of the API pane, enter the following in Raw format. This is an SQL query to fetch the data from the rental table and we are using server-side pagination to display data in the table widget (rentalTable), hence the limit and offset are set in the query.

{
    "operation": "sql",
    "sql": "SELECT * FROM movies.Rental LIMIT {{rentalTable.pageSize}} OFFSET {{(rentalTable.pageNo - 1) * rentalTable.pageSize}}"
}


  • Bind the data from this query under Table Data property of the rentalTable table using the following snippet


{{get_rental.data}}


  • You will notice the table widget populates with results from the query.
  • Next, we will bind data to the widgets on the Update form to the right of the table. When a user click on the table row, the corresponding details should be displayed on the form.
  • For the Rental Update form, set the widgets in the following manner. Notice that we are manually adding the values in the Status select widget so that the status of the rental can be updated on the form.
CleanShot 2022-06-07 at 13.21.52@2x.png
  • Create a query to update the Rental status and Returned date on this form.
  • On the Rental Inventory page, click on the + icon next to Queries/JS. Select New Blank API
  • On the API pane, rename Api1 to update_rental and select the POST method. Repeat the same steps as above for the URL endpoint and the Headers
  • In the Body tab of the API pane, enter the following under Raw tab

{
    "operation": "update",
    "schema": "movies",
    "table": "Rental",
    "records": [
        {
            "id": {{rentalTable.selectedRow.id}},
            "status": {{status.selectedOptionValue}},
                        "return_date": {{returnedDate.selectedDate}}
        }
    ]
}


  • Hook this query on the onClick event of the Submit button on the Update Rental form. On success of this query also run the get_rental query to repopulate the table widget with updated data.
Screenshot_2022-05-02_at_3.26.36_PM.png
  • Create API query named search_customer with headers same as before with the following code snippet under Body tab of the API pane in Raw format


  {
      "operation": "search_by_value",
      "schema": "movies",
      "table": "Customer",
      "search_attribute": "email",
          "limit": 10,
      "search_value": {{`*${rentalCustEmail.filterText}*`}},
      "get_attributes": [
          "id", "email"
      ]
  }


  • Create another API query named search_film with the following code snippet under Body tab of the API pane in Raw format.

  {
      "operation": "search_by_value",
      "schema": "movies",
      "table": "Film",
      "search_attribute": "title",
          "limit": 10,
      "search_value": {{`*${filmTitle.filterText}*`}},
      "get_attributes": [
          "id", "title"
      ]
  }


  • Create a third query name new_rental to add new rental information with the following code snippet under Body tab of the API pane in Raw format.

  {
      "operation": "upsert",
      "schema": "movies",
      "table": "Rental",
      "records": [
          {
                          "film_title": {{filmTitle.selectedOptionValue}},
                          "rental_date": {{moment().utc()}},
                          "staff_id": {{appsmith.store.user.username == 'assistant'? 2: 1}},
                          "customer_email": {{rentalCustEmail.selectedOptionValue}},
                          "status": "borrowed"
          }
      ]
  }


  • Open the modal by clicking the New button on the Rental tab. On Customer select widget write the following code snippet to populate the customer email ids from the search_customer query.
  •  {{search_customer.data.map(c => ({label: c.email, value: c.email}))}}
Screenshot_2022-05-02_at_5.46.54_PM.png
  • Similarly, populate the Film select widget from the search_film with below code snippet.

{{search_film.data.map(m => ({label: m.title, value: m.title}))}}


  • Set the new_rental query to run on the onClick event of the Confirm button on the modal.
Screenshot_2022-05-02_at_6.01.56_PM.png
  • Repeat the above steps for the Film Tab.
  • The Update Form on the Film tab has the following data bindings
CleanShot 2022-06-07 at 13.26.37@2x.png
  • Create an API query named update_film with the following code snippet under Body tab of the API pane in Raw format. Bind this query to run on the onClick action of the onClick event of the Submit button on the Update Film form.


{
    "operation": "update",
    "schema": "movies",
    "table": "Film",
    "records": [
        {
                    "id": {{filmTable.selectedRow.id}},
                    "rental_duration": {{ufDuration.text}},
                    "rental_rate": {{ufRate.text}},
                    "replacement_cost": {{ufCost.text}}
        }
    ]
}



  • Let’s configure the queries to run to add new film data. Create API query named create_film with headers same as before. Add the following code snippet under Body tab of the API pane, enter the following in Raw


  • Open the modal by clicking the New button on the Film tab. Set the create_film query to run on the onClick event of the Confirm button on the modal. Close the modal and rerun the get_film query to refresh the Film table widget on success of the query.
Screenshot_2022-05-02_at_6.24.53_PM.png
  • Finally on the Customer page, write queries for the search input widget (customerSearchInput) and for displaying data in the list(customerList) below.
  • Create query called get_customers with the following under Body tab of the API pane.

{
    "operation": "search_by_value",
    "schema": "movies",
    "table": "Customer",
    "search_attribute": "email",
        "limit": 10,
    "search_value": "{{`*${customerSearchInput.text}*`}}",
    "get_attributes": [
        "id", "email", "first_name", "last_name"
    ]
}


Bind this query to the onTextChanged action of the customerSearchInput box


{{get_customers.run()}}


  • Bind the results of this query {{get_customers.data}} to the Items property of the customerList box
Screenshot_2022-05-02_at_4.41.35_PM.png
  • Let’s configure the queries to run to add new Customer data. Create API query named new_customer with headers same as before. Add the following code snippet under Body tab of the API pane, and enter the following in Raw

  {
      "operation": "upsert",
      "schema": "movie",
      "table": "customer",
      "records": [
          {
                          "first_name": {{ncFNameInput.text}},
                          "last_name": {{ncLNameInput.text}},
                          "email": {{ncEmailInput.text}}
          }
      ]
  }


  • Open the modal by clicking the New button on the Film tab. Set the new_customer query to run on the onClick event of the Confirm button on the modal. Close the modal on success.
Screenshot_2022-05-02_at_6.22.38_PM.png

Step 7: Control access to information based on user roles

  • On the Rental Inventory page, set the Visibility of the Tab widget to show only if the login process returns tokens on success. Toggle the JS button next to the Visible property to enter the following code snippet

{{!!appsmith.store.user.token}}


Screenshot_2022-05-02_at_2.44.29_PM.png
  • The Rental tab is visible to both the Manager and Assistant roles so we leave its visibility as is
  • The Film and Customer tab should only be visible to the Manager
  • The Visible property of the individual tabs can be accessed by clicking on the gear icon next to the tab name
Screenshot_2022-05-02_at_4.51.56_PM.png
  • Add the following snippet of code in the Visible property of both the tabs

{{appsmith.store.user.username !== 'assistant'}}

Step 8: Configure the Logout button

When the user clicks on the Logout button, we will clear the username and token information in the store variable and redirect the user to the Login page. Add the following snippet of code on the onClick event of the Logout button.


{{storeValue('user', {}); navigateTo('Login')}}


Screenshot_2022-05-02_at_4.46.03_PM.png

So far, we've done a great job. The last part of this project will deploy our application. On the dashboard's top right section, click on the 'Deploy' button. You can also deploy this application by connecting to a Git repository. Our application is now deployed!

If you're interested in using a database not listed on our website as an integration, please let us know about it by raising a PR on Github, and we will do our best to include it at the earliest.

Join our growing community on Discord, and follow us on Youtube and Twitter to stay up to date.

Build a Low Code Brex Client to Automate Operations
9
May
2022
Tutorial

Build a Low Code Brex Client to Automate Operations

Build a Low Code Brex Client to Automate Operations
Stephen Tillman
0
 minutes ↗
#
apis
#
app-development
Tutorial

Some things are fantastic together. 🍔🥤

In particular, REST APIs and Low code dovetail nicely.

Although APIs simplify development, they also demand a level of programming skill and technical ability. Low code frameworks like Appsmith can provide a visual layer on top of the API that empowers non-technical audiences and citizen developers to build client applications.

There is much value in simplifying the development process where we can. Low code works best for development projects where the problem domain is well understood and there are very few use cases. REST API clients are well suited to that extent - the API contract itself serves as a kind of blueprint for the client application. Take, for instance, the Brex APIs.

Brex offers several APIs that range from Onboarding and Payments to Teams and Transactions. Brex admins can plug into these APIs to build powerful workflows and custom automations. To demonstrate, we'll build an Appsmith dashboard that will connect to your Brex account.

Key Takeaways

  • Appsmith has a REST interface that allows us to create and modify query objects. A query object is a portable, reusable construct that defines parameters needed for a single API call. We'll use several query objects to engage the Brex APIs.
  • Building a multi-page interface with Appsmith is incredibly simple and well-documented. The platform provides a visual way to build pages using widgets and drag/drop functionality. However, unlike the global Appsmith store, page resources are page-scoped and cannot be referenced across different pages. Despite that, it is still possible to move or copy resources from one page to another.
  • We'll use JavaScript Promises to simplify asynchronous workflows. This will enable us to launch multiple API calls concurrently and then handle the responses elegantly. Normally, this is a challenge because API calls rely on the network and conclude at inexact points in time. To overcome this, we used to apply callback functions, but JavaScript Promises are an improvement over callbacks.

What are we building?

In this tutorial, we'll create an Appsmith tool that leverages the Brex APIs to perform bulk operations on your Brex account. By uploading a CSV file, you'll be able to create credit cards, users, and vendors. These changes will be reflected in your Brex dashboard immediately. Our tool will also support terminating cards and deleting vendors.

As it is not intended for production use, this application doesn't attempt to be either complete or systematic. It is more like a demo project. Rather than serve as a proper software solution, the final application is meant to demonstrate what is possible using Appsmith and the Brex APIs.

For context, this tutorial depicts the reader as a fictional Brex customer in order to provide a frame of reference and bring meaning to the sample CSV files. Pretend that you are an outer space company that issues Brex credit cards to your colleagues. The cardholders have personal cards as well as other cards designated for expenses such as Equipment Repairs, Launch Services, and Telecom. You will also define fictional Vendors: General Atomics, Orbital Transport Services, Space Food Systems. Let's suppose you are building this application to automate a few back office operations. You have chosen to build it using Appsmith.

What do I need?

First, you'll want to sign into Appsmith and create a new application. Next, sign in to your Brex account and generate a user token with Read/Write permissions for Cards, Referrals, Users, and Vendors. Appsmith will use this token to authorize API calls.

To confirm that your token is working, you can perform a quick sanity check with curl:

COPYcurl --request GET 'https://platform.brexapis.com/v2/users/me' \
--header 'Authorization: Bearer <your-token>'

The response will resemble the following:

COPY{
   "id": "cuuser...",
   "first_name": "Michael",
   "last_name": "Collins",
   "email": "mcollins@example.com",
   "status": "ACTIVE"
}

Postman

Alternatively, you can use Postman to test API calls. In fact, the Brex Developer workspace allows you to experiment with every endpoint documented in the Brex Developer Portal.

Appsmith Echo API

Consider using the Appsmith Echo API to spare production API calls.

COPY[POST] https://mock-api.appsmith.com/echo/post

While testing your Appsmith tool, sometimes you will need to invoke non-idempotent API endpoints such as Create card and Invite user. Instead of exercising the live endpoints, you can create an API datasource that relies on the Appsmith Echo API:

COPYfor(let i = 0; i < 5; i++) {
  echo_post.run(onSuccess, onError, params);
}

To mock HTTP status codes and errors, you might try httpstat.us.

Disposable Inbox

For testing user invites, I recommend a disposable email system like Mailinator or Temp Mail.

Git Repo

There's a companion repo that contains sample CSV files and supporting JavaScript code for this tutorial. You can also use Appsmith's Import-Export feature to migrate the demo application to your own account.

Brex APIs

The base URL for all Brex APIs is https://platform.brexapis.com.

  1. Use this URL to create an authenticated API datasource called brex-prod.
  2. Select Bearer Token for the Authentication Type.
  3. Supply your Brex user token.
  4. Click Save.

You should now have a datasource that we can use to create Queries.

New query objects will show in the left side panel, under QUERIES/JS. For example, here I've created a query for the Get current user endpoint:

get-current-user-api-pane

Now, you can create new query objects from the brex-prod datasource. The following search box will appear when you click the + icon next to the QUERIES/JS menu option:

brex-prod-datasource

Going forward, we'll create several queries to support our application.

Onboarding API

The Onboarding API allows you to refer your customers and personal contacts to Brex. You might use the Create referral endpoint as part of the Brex Referral Program.

Unlike the Get current user endpoint, Create referral is a POST endpoint that requires a JSON body.

create-referral-json-body

Later on, we'll discuss this.params. For now, understand that it is possible to run the create_referral query object and pass parameters into it, like so:

COPYconst params = { referral_code, email, first_name, last_name };
return create_referral.run(params); // always return the promise

Team API

The Team API lets you manage users, departments, locations, and cards. For this example, we'll manage users and cards, starting with the Invite user endpoint, which allows you to invite a new team member as an employee. Through the dashboard, Brex admins can assign various role types to the employee, but team members created through this endpoint will bear the Employee role type by default.

Your invite_user query object will POST to /v2/users. The request body should match the following:

COPY{
   "first_name": {{this.params.first_name}},
   "last_name": {{this.params.last_name}},
   "email": {{this.params.email}}
}

Idempotency

Under the Headers tab, be sure to generate a random string value for the Idempotency-Key:

idempotency-key

Idempotency is well beyond the scope of this tutorial. But, in short, the idempotency key ensures that the API server will only process a non-idempotent request once.

For a moment, consider network interruptions that may cause downstream services (or even the application itself) to perform a retry. Without an idempotency, the server would attempt to process the same request again. The idempotency key helps the API server keep track of whether the operation was already performed or not.

Notice that the code to generate the Idempotency-Key includes a reference to Lodash: _.random(1000). Lodash, among other libraries, is built into the Appsmith platform, which is super handy.

Create Card

The create_card query object also requires an Idempotency-Key, and will POST to /v2/cards. The request body is:

COPY{
   "owner": {
       "type": "USER",
       "user_id": {{this.params.user_id}}
   },
   "card_name": {{this.params.card_name}},
   "card_type": "VIRTUAL",
   "limit_type": "USER"
}

The Create card endpoint also accepts other parameters, card types, and limit types, so check out the developer docs. There's also a spend_controls parameter that allows you to define a spend limit for the card. This limit can be set to refresh each month, quarter, year, or never (for one-time use).

Terminate Card

We can also reference {{this.params...}} in the query object URL. For example, the terminate_card query object will POST to the Terminate card endpoint, which has a URI parameter, {{this.params.card_id}}:

COPY/v2/cards/{{this.params.card_id}}/terminate

The request body for terminate_card:

COPY{
 "description": "demo",
 "reason": "OTHER"
}

There are also other reason codes such as CARD_LOST, CARD_NOT_RECEIVED and FRAUD, but for this example, we'll stick with OTHER.

Note that the Idempotency-Key is not required, because card termination is idempotent by definition. In other words, terminating a card multiple times has the same effect as terminating a card once.

Payments API

The Payments API allows you to initiate and manage payments and vendors from your Brex Cash account. We'll use the Create vendor endpoint as an example. In a production application, you would also include vendor payment information to enable ACH, wire, or cheque payments from your Brex Cash account. But, for this example, we'll omit the vendor's payment type. You can also add vendor payment information from the dashboard - How do I manage my vendors on Brex Cash?

Create Vendor

The create_vendor query object will POST to /v1/vendors. This endpoint requires an Idempotency-Key and the request body is:

COPY{
  "company_name": {{this.params.company_name}}
}

Delete Vendor

The delete_vendor query object will send DELETE requests to /v1/vendors/{{this.params.vendor_id}}. There is no request body.

Initial Data Loading

The following query objects will enable us to populate tables on page load. To ensure that Appsmith pulls the initial dataset each time, you can configure each query object to run on page load:

QueryEndpointget_cardsList cardsget_usersList usersget_vendorsList vendors

This option is located under the Settings tab inside the query object:

query-settings

Appsmith Pages

The goal of our app is to provide a user-friendly way to create Brex credit cards, vendors, invites, and referrals. In this section, we'll envision the page layout and breifly touch on a few key points. You'll use a drag/drop interface to build the UI. But, before we get started:

  1. Rename Page1 to Cards.
  2. Add a page for Users and another page for Vendors.
  3. Move get_users, create_referral and invite_user from the Cards page to the Users page.
  4. Move get_vendors, create_vendor and delete_vendor to the Vendors page.

Now that our work is cut out, we'll begin creating each page.

Cards

Use the Appsmith widgets to create the following page to your ability. Note that the green Upload widget is a file picker, not a button.

cards-page-design

Make sure the Data Format property is set to Text for each file picker:

fp-text

Users

The Users page has a Tabs widget with two tabs, one for invites and one for referrals. You can drag each Table widget into the appropriate tab.

users-page-design

The Referrals tab:

users-page-referrals

Vendors

The Vendors page is almost identical to the Cards page. In fact, you can select every widget on the Cards page and copy/paste them onto the Vendors page. Of course, you'll also need to adjust the widget properties and table data.

vendors-page-design

Application Logic

Our application is starting to take shape. We now have an end-to-end skeleton system. Next, we'll incrementally add functionality to each page, incorporating the query objects we created earlier. We'll also learn about JS Objects, which allow us to define handler functions that we can bind to the page widgets.

Page Load

Earlier, we created a few query objects to run on page load. Now, we'll use them to populate our table widgets. As stated in Running APIs on Page Load, "If we connect an API response to a widget, Appsmith automatically runs that API on page load..."

In effect, this means that binding {{get_cards.data.items}} to the Table Data property for tbl_cards will populate the table. However, for this tutorial, we only need the card id and card_name fields from each card. So, we'll write some additional code to remove the unwanted fields:

COPY// bind this to tbl_cards - Table Data property
get_cards.data.items
 .filter(card => card.status == "ACTIVE") // only get ACTIVE cards
 .map(card => ({ id: card.id, card_name: card.card_name }))

Likewise, we initialize tbl_invites and tbl_vendors:

COPY// bind this to tbl_invites - Table Data property
get_users.data.items
 .filter(item => item.status == "INVITED") // only get INVITED users
 .map(item => ({ email: item.email, name: `${item.first_name} ${item.last_name}` }))

// bind this to tbl_vendors - Table Data property
get_vendors.data.items.map(vendor => ({ id: vendor.id, company_name: vendor.company_name }))

JS Objects

In earlier versions of Appsmith, there was only support for writing small code snippets to data bind page widgets. But, Appsmith now supports JS Objects, which enable multi-line JavaScript code and reusable functions.

To create a new JS Object, click the + icon next to the QUERIES/JS menu option, and find the New JS Object option.

new-js-object

Create an object for each page: cards_object, users_object, and vendors_object.

Cards

Replace the contents of cards_object with the following code:

COPYexport default {
   upload: () => {
       showAlert('Cards created!', 'success');
   }
}

We'll revisit this code shortly. At the moment, let's go back to the page editor and bind {{cards_object.upload()}} to the file picker's onFilesSelected event:

create-card-filepicker

If you are curious, deploy the application and upload a file to the Cards page. You should receive a Cards created! notification.

The cards_object.upload method will leverage the create_card query to issue virtual cards. To follow along here, you'll need your Brex cuuser ID, which you can obtain by running the get_current_user query. Place your ID into a CSV file, formatted like this:

COPYcard_name,user_id
Michael Collins,cuuser...

Later on, we'll upload this file to the Cards page.

Reading CSV Files

The following code will read lines from a CSV file, assuming that your file picker is called fp_cards:

COPY// get the first uploaded file
const csv_file = fp_cards.files[0];

// collect each line from the csv file
const csv_lines = csv_file.data.split("\n");

// omit csv header and blank lines
const rows = csv_lines.slice(1).filter(row => row.length > 0);

Simplified:

COPYconst rows = fp_cards.files[0].data.split("\n")
                    .slice(1).filter(row => row.length > 0);

Iterating API Calls

To smoothen the discussion around asynchronous code and JavaScript promises, we'll be using a helper function called loop to iterate API calls. For reference, the full loop implementation is here, but we'll strictly focus on understanding its usage:

COPY// visit each row
return cards_object.loop({
 collection: rows, // assign rows as the collection
 onReadLine: () => {
   // do this on every row
 },
 onEnd: () => {
   // do this after the loop ends
 }
})

The loop helper calls onReadLine once per row. On each loop iteration, we can pass card_name and user_id into create_card.run():

COPYonReadLine: (card_name, user_id) => {
 // be sure to always return the promise,
 // otherwise this will not behave as expected
 return create_card.run({ card_name, user_id });
}

When the loop ends, we report the number of cards created successfully, and then call get_cards.run so that the new items appear in tbl_cards:

COPYonEnd: () => {
 const count = appsmith.store.success_count;
 if (count > 0) {
   showAlert(`${count} cards created!`, "success");
 }
 get_cards.run();
}

Once you re-deploy the application and upload a valid CSV file, your card will show in the Brex dashboard, under Card > Manage cards:

michaels-card

Last, but not least, we have cards_object.terminate. Bind this method to btn_terminate_cards - onClick event:

COPYterminate: () => {
   // clear variables
   cards_object.reset();

   // get comma-separated values from the textbox
   const rows = txt_card_ids.text.split(",").map((id) => id.trim());

   // visit each row, terminate card
   return cards_object.loop({
     collection: rows,
     onReadLine: (card_id) => {
       return terminate_card.run({ card_id });
     },
     onEnd: () => {
       const count = appsmith.store.success_count;
       if (count > 0) {
         showAlert(`${count} cards terminated!`, "success");
       }
       get_cards.run();
     },
   });
 }

Users

The Users page involves many of the same techniques and concepts discussed earlier. However, there are two tables involved here. We'll need to refresh one of the tables, depending on whether the CSV file is intended for referrals or invites.

I should mention that an invite asks someone to join your Brex account as a team member, whereas a referral prompts someone to sign up for their own Brex account.

Invites vs Referrals

Creating an invite sends an email to the recipient:

brex-invite

On the other hand, creating a referral generates a personalized invite link to an onboarding flow. You can find your referral code at dashboard.brex.com/referrals. When the prospect visits their personalized link, they will see a pre-filled form containing data values sent through the Create referral API call:

brex-referral

When the CSV file is uploaded, we can inspect the header row to determine if the file contains referrals or not - referrals have a referral_code column while invites do not:

COPY// invites csv header: "first_name,last_name,email"
// referrals csv header: "referral_code,first_name,last_name,email"
let is_referral = rows[0].indexOf("referral_code,") == 0;

// ...

return is_referral
       ? users_object.createReferrals(rows)
       : users_object.createInvites(rows)

For brevity, the full implementation code is shown here.

Referral Data Store

Something to note about the Create referral endpoint is that it returns the referral id and the referral_signup_url, but it does not return the applicant details (first name, last name, and email). Instead, the API consumer is expected to store and handle their own Brex referrals securely, as they contain sensitive information about the applicant.

Why do we need a data store?

At first glance, this might seem trivial. Perhaps, we don't need a referral data store. Maybe we could just create the referrals and then use the List referrals endpoint to load the recent items. However, the List referrals endpoint does not return any applicant information either.

So, by design, we need the data store to establish a link between the applicant details (passed into create_referral) and the referral id (returned from create_referral).

Without a data store, it's also not possible to seed tbl_referrals on page load. The List referrals endpoint doesn't return any applicant information, so we need to query the data store instead and then use that response data to populate tbl_referrals.

Implementing the data store

I'm using a serverless database (Fauna) to host the data store for this tutorial, but the type of database you use is unimportant. It is only important that the data store is accessible via a REST API, so that we can easily connect to the data source and create query objects:

QueryEndpointadd_referralgraphql.us.fauna.com/graphqlget_referralsgraphql.us.fauna.com/graphql

Fauna exposes a GraphQL API. Please see the the wiki for more details about this as it relates to add_referral and get_referrals.

Storing the referral data

Now that the data store is in place, we can persist the referral id and referral_signup_url along with the applicant information:

COPY// get response data and csv row
onSuccess: ({ id, referral_signup_url }, row) => {
 // get applicant info from the row
 const [referral_code, first_name, last_name, email] = row;
 // store the referral data
 add_referral.run({
   id,
   name: `${first_name} ${last_name}`,
   email,
   referral_signup_url,
 });
},

Get referrals on page load

Also, remember to configure get_referrals to run on page load:

COPY// bind this to tbl_referrals - Table Data property
get_referrals.data &&
get_referrals.data.data &&
get_referrals.data.data.allReferrals.data

Vendors

Implementation of the Vendors page is left as an exercise for the reader. Here are some things to keep in mind:

  1. The fp_vendors file picker needs an event handler for onFilesSelected.
  2. The create_vendor query object has a company_name parameter.
  3. The delete_vendor query object has a vendor_id parameter.
  4. Bind {{appsmith.store.vendors_arr}} to tbl_vendors.
  5. Uploading vendors.csv should create three new vendors in your Brex dashboard.

The full vendors_object implementation is here. You can also create multiple vendors by using the bulk upload tool in your Brex dashboard.

Error Handling

Thus far, we've only explored the happy path. If we return to the Cards page and upload cards.invalid-user-id.csv the create_card query will fail. Thankfully, Appsmith will handle this exception and display an error message.

fail-create_card

But, imagine if you were to upload the following CSV file:

COPYcard_name,user_id
Space Mountain,invalid-user-id
Cargo Dragon,cuuser...
Planet Express,invalid-user-id

In this case, the API call would fail on Space Mountain and Planet Express, but the default error handling would not be able to detect which rows failed. To correct this, we'll need to implement the error handling ourselves.

During cards_object.loop(), whenever onReadLine fails, the onError function will trigger. We can implement onError to display a message:

COPYonError: ({ row }) => {
 const [card_name] = row;
 const message = `failed to create card "${card_name}"`;
 showAlert(message, "error");
 return message; // return message to the loop helper
}

The loop helper also keeps track of errors. There's a has_errors flag, which is a boolean that indicates when any errors have occurred. There is also an errors_arr collection where we store each error message for later display in tbl_errors.

The has_errors flag will determine if the red Icon Button is visible. Set its Visible property to {{appsmith.store.has_errors}}. Also bind its onClick handler to {{showModal("error_modal")}}. This button will launch a Modal that contains a table bound to {{appsmith.store.errors_arr}}:

error-modal

Conclusion

The beauty of Appsmith is that you can migrate this application to your own workspace and repurpose it for your own needs. Here, we've touched on a few Brex API endpoints. We've also learned how to create an Appsmith dashboard that allows Brex admins to create and terminate Brex cards and refer and invite Brex users.

I encourage Brex admins to build and share custom Appsmith workflows that tap into the Brex APIs. There is much value in simplifying the development process where we can. Low code tools like Appsmith can provide practical advantages to Brex admins who need them, but they can also change the perspectives and attitudes of those who do not.

The views expressed in this post are my own and have not been reviewed or approved by my employer (Brex, Inc.).

Build a Contact Application with Django
4
May
2022
Tutorial

Build a Contact Application with Django

Build a Contact Application with Django
Anita Achu
0
 minutes ↗
#
analytics
#
announcement
#
app-development
Tutorial

A contact application is a database that collects and stores user contact data. The contact app is a widely used application, similar to the contact application on your mobile phone, that stores data such as user contact names, phone numbers, email addresses, etc. Businesses can use this application to manage their customers' information and store personal contact data.

This tutorial primarily focuses on integrating a contact API in Python using the Django Rest Framework. This application will have functionalities that allow users to create, edit, and delete contact data. While this goes on the backend of the application, we will create the interface of our application using Appsmith's pre-built UI widgets.

Appsmith is a powerful open-source low-code framework for creating internal tools with features such as pre-built UI widgets that connect to multiple data sources: APIs, databases, GraphQL, etc., with support for OAuth 2.0 and CURL.

Appsmith allows you to create web application interfaces with little or no code. You don't need to be a developer to create an application dashboard using Appsmith. Using Appsmith's drag-and-drop UI widgets, we will create a dashboard for our application.

Prerequisites

Project setup: Building a contact book API

Creating a virtual environment

We will begin by creating a virtual environment for our project. The essence of a virtual environment is to create a separate environment for all installed packages and dependencies.

The command below shows how to create a virtual environment in your terminal:

pip install virtualenvvirtualenv env


Activate our virtual environment

For Windows:

env\Scripts\activate

For Mac/Linux:

source env/bin/activate

Virtual environment activated!

Cloning a repository

Next, we will be cloning an already existing repository built with the Django Rest Framework. This repo contains a contact application with functionalities that allow users to create, edit, and delete contact data.

To clone the repo, run these lines of code in your terminal:

git clone https://github.com/Anitaachu/contactAPI.gitcd contactAPI


Dependencies installation

Once this is completed, we will be installing a couple of dependencies and packages required for this project using the pip These packages are already contained in your cloned requirements.txt file.

Run this command to create a requirements.txt file and install the packages:

pip install -r requirements.txt


Next, migrate the data to the database and create a superuser. To this by running the following commands:

python manage.py migratepython manage.py createsuperuser

Testing the application

Next, let's test this application locally, using the following command: python manage.py runserver

In your browser hit the endpoint http://127.0.0.1:8000/. You can also access the admin page using this URL http://127.0.0.1:8000/admin/

list_contact
Admin_page

Great! Our application is running! 🎉

Getting started with Appsmith

With our API up and running, the next phase of this project is creating an interface using Appsmith pre-built widgets and connecting these widgets to our data source (API). We will be doing this by writing some queries that will be implemented with the widgets.

Let’s dive in!

Connecting to a Datasource

It takes a few minutes to connect to a datasource, and you can develop tools on the database of your choosing. You can either connect to a database, an API, or both. For this project, we will connect Appsmith to a deployed API using the API we earlier created. The deployed API can be accessed using this URL.

appsmith_dashboard
  • Ensure the API you intend to connect is already deployed. You can use Heroku or any other deployment service.

Add the URL of your deployed API and click on ‘run'.

datasource

Datasource successfully connected!

Now let’s get to work!

Creating a dashboard with the Appsmith widget

With Appsmith, you can build a fully customized interface with no code. Appsmith has many pre-built UI widgets such as tables, forms, buttons, boxes, images, and more, all available to help you create exciting applications.

Let’s begin! Firstly, let's create a table that will display our contact data.

Follow these steps:

  • From the widget section, drag and drop the table widget onto the canvas in this manner:
dashboard
  • Edit the default data from the property pane and add the column names as contained in our database. As contained in our database, the column names include "_first_name", "last_name", "phonenumber", "email", "address", and "birthday."
dashboard
  • Next, edit the Table Data property in Table Widget’s property pane to {{Contact_API.data}} in other access data from the query.
dasboard

Next, we will create a button widget that will be used to create contacts. When a user clicks this button, it navigates to another page that contains a form widget.

Adding a button and form widget

Drag and drop the button widget into the canvas.

dashboard

In the label section, change the ‘submit’ label to 'create contact'. Next, edit the button widget, in the Events > onClick > Navigate to.

dashboard

Under "Page Name or URL" type in 'Page 2'. By doing this, when we click on the "Create contact" button, it navigates us to a new page that will take us to the contact form.

Lastly, click on the "+" icon at the top left to add a new page.

Form widget

This new page will contain a contact form that will be used to add a new contact, using input fields where users can enter the contact data they wish to create.

Let’s create a form using a form widget with these few steps:

  • From the widget section, drag a form widget into the canvas.
form_widget
  • Change the "Form" label to "Create contact".
  • Next, drag and drop text widgets into the form widget we just created. Edit the label name to first name, last name, etc. In this manner:
form_widget
  • Add the input widget to the canvas. This widget will allow the user to enter their contact name, phone number, address, etc.
form_widget
  • Add functionality to the submit button. To do this, create a new query on the right side of the page.
form_widget
form_widget
  • Add connect the query to the submit button.
form_widget
  • Lastly, set the body property of your datasource to:
{"first_name": "{{Input1.text}}","last_name": "{{Input2.text}}","phone_number": "{{Input3.text}}","email":"{{Input4.text}}","address":"{{Input5.text}}","birthday": "{{Input6.text}}"}


By doing this, a connection will be created between the widget and the datasource.

Now let’s test out our widget to ensure that it's functioning. Firstly, on the contact dashboard, click on the "Create Contact" button. The button would redirect to another page that contains a contact form.

widget_5_new

Fill out this form and hit the submit button. You will notice that contact details that are added through the form are displayed on our application dashboard.

form_widget

So far, we have been able to create a form widget where users can create contacts, and these contacts will be displayed on our dashboard.

Great!

Asides creating contacts, contact applications also have features where users can edit contacts or delete contacts that are no longer needed. Let’s add the edit and delete contact buttons and write queries that will connect these buttons to our datasource.

Edit contact button

In our application dashboard, add an edit button. This button will also be connected to our datasource. Let’s work on our edit button.

  • Step 1: In the application dashboard, create a new column named "edit contact".
  • Step 2: Next, click on the Settings symbol in the “Edit Contact”* column to add some functions to it.
  • Step 3: Replace the following:
  • Column Type: Choose ‘Button’.
  • Label: Replace ‘Action’ with ‘Edit’.
  • onClick: Choose ‘Open modal
  • Lastly, under 'Modal Name', create a new modal.

When you click on the edit button, it spins up a modal. We will edit this modal and add some queries to it to enhance its functionality. To do this:

  • First, create a text and input widget similar to that of the form widget in the modal. This way:
modal
  • Add a new datasource and enter the URL of the datasource.
datasource

Now you can edit a contact by clicking on the edit button and adding new data to replace the former contact data.

For the delete function, we simply repeat the same process as that of the edit button. However, the modal of the delete may differ. The Delete modal should appear like this:

modal

Just as we did for the first modal, create a query that will connect the delete button widget to a data source.

button_widget

Set the body property of your datasource to: {{Table1.selectedRow.id}}

Lastly, execute a query under Events > onClick. This button will query data from the deleted datasource you have created.

button_widget

Our widgets and datasources are well implemented and functioning properly.

Deployment

So far, we have done a great job. The last phase of this project will deploy our application. On the right section of the dashboard, click on 'Deploy'. You can also deploy this application by connecting to a Git repository.

Our application is deployed! 🎉

Finally, to test the work we have done so far. Try creating a new contact:

deployment

We will also test the delete button to ensure it's working as well:

delete_button

Successful!

In this tutorial, we created an amazing user interface for our contact application with low code. I hope you had fun building!

Happy coding!🙂

Introducing JSON Forms in Appsmith
21
April
2022
Announcement

Introducing JSON Forms in Appsmith

Introducing JSON Forms in Appsmith
Somangshu Goswami
0
 minutes ↗
#
announcement
#
app-development
#
applications
#
widgets
Announcement

Forms are a core part of most internal tools since its one of the major ways in which data is created or updated. Today, we're introducing the JSON Form Widget (documentation), which allows for a fantastic form creation experience and has been one of our top requested features.

The JSON form widget is helpful for quickly generating (dynamic or otherwise) forms from JSON fields.

Here are some highlights of this widget:

Generate Forms from Database Queries, APIs, or JS Objects

Once you drag a new JSON form widget, you will see a default form rendered with some details. You can update the source data field to infer data and then generate the form. This can be bound to any query or variable containing JSON data, such as DB queries, APIs, or JS Objects. The JSON Form widget can be bound to any other widget in Appsmith as well.

Auto Generate Form When Your Data Changes

The form fields are generated according to the source data when you enable an auto-generated form. Fields are generated according to the key-value pairs in the source data. Whenever there is a change in the source data, the form fields get updated automatically.

Configure Fields As You See Fit

Field configuration shows all the fields generated automatically in the forms. You can edit the fields to tweak properties like the field type and default value and bind specific actions by using editable properties. Most fields use the underlying data type-specific widget's properties to allow a full level of customization just like the widget would. For example, if the input type is text input, the editable properties are similar to the input widget in Appsmith.

  • Array Fields allows you to add, remove, and update a group of fields together.
  • Object Fields allow you to group fields together.
  • Add New Field, disable invalid forms (and control them further with JS), and control a widget's visibility on the app page to create highly customized dynamic forms.

Some of the ways that we've seen our users use the JSON form are:

  • Customer service executives select a form template and customize it for a customer. This is stored in a database and then sent over to the customer.
  • Users can create dynamic sign-up forms, as having both the Sign-in and Sign-up forms on the same page. Conditional switching between forms is effortless because you don't need to create two forms; you only need to change the JSON data.
  • Marketing teams are using the JSON form to create personalised form-based campaigns and much more!
Note: It’s live on the cloud app and will be live on the self-hosted version very soon.

Want to explore the JSON Form in detail? Head over to the JSON Form documentation page to learn more.

Build a Tool to Generate PDF Files with APITemplate and n8n
23
March
2022
Tutorial

Build a Tool to Generate PDF Files with APITemplate and n8n

Build a Tool to Generate PDF Files with APITemplate and n8n
Vihar Kurama
0
 minutes ↗
#
automation
#
apis
#
dashboard
#
app-development
Tutorial

Information is the lifeline of any business, and to keep it alive and well, businesses have to transfer information to their various stakeholders like investors, bankers, suppliers, customers, government, etc. One of the simplest and the most effective ways of transferring information is using PDF files. These PDF files can be generated in different ways, but it involves lots of coding and configuration on your frontend and backend applications. To make this process easier on Appsmith (low-code framework to build internal tools), we created a workflow on n8n that uses APITemplate and simple webhooks.

This tutorial is a step-by-step guide on generating and exporting PDF files from data on your Appsmith application. Let's dive in!

Getting Started: Setting up Appsmith and the Data to Export

The first step is to create an account on Appsmith. In this tutorial, I'll be using the cloud version of Appsmith, but you can always choose to use Appsmith locally or self-host it on your server.

  • Navigate to appsmith.com and sign-up for a new account if you're a new user or login to the existing one.
  • Next, create a new application under your preferred organization. You'll see an editor with everything you need to build your internal application.

Now, let's create a table from the mock database already provided on Appsmith.

  • For this, click on the + icon next to the Datasources on the left sidebar under Page1.
  • Now choose the users database (Postgres) under-sample databases section.
CleanShot 2022-03-17 at 00.35.15@2x.png
  • With this, you should see users' databases under your data sources section on the left sidebar. Now create a new query by clicking on Create New button from the user's datasource.
  • This will create an empty query named Query1, rename this as getUsers and paste the following SQL query:

SELECT * FROM users ORDER BY id LIMIT 10;


  • Hit the Run button on the top right to execute this query; it will return details of the first ten users from the user's table on the database.

Now let's bind this on a Table widget and then create a workflow to export it into a PDF file.

  • To bind the query on a table widget, click on the + icon next to the widget and search for the table under the Widgets tab.
  • Drag and drop the table widget onto the canvas and open its property pane by selecting the table on the canvas. You should see all the table configurations on the side right bar.
  • Next, update the Table Data property to the following:
{{ getUsers.data  }}


  • Here, we use the moustache bindings to bind the data from the query onto the widget. You can write JavaScript anywhere across appsmith inside these bindings.

Following is what the application looks like now:

CleanShot 2022-03-17 at 00.54.43@2x.png

Excellent, our data is now ready. Now let’s create a workflow on n8n to generate PDF using APIs from APITemplate.io.

Setting up APITemplate.io

If you are new to these tools, the following is a quick intro to help you get started:

APITemplate.io: APITemplate helps auto-generate images and PDFs with Zapier, Integromat, N8n ow with a simple REST API.

Now let’s create a free account on APITemplate; you will be redirected to your dashboard after signing up. Navigate to the Manage Templates tab and create a new PDF template.

The template here is how you want your PDF to be organized this tutorial; I’ll be using the basic table template provided under the PDF template section.

Since our goal is to export the data on the Appsmith table, I’ve navigated to the HTML editor and removed all the unnecessary HTML content.

CleanShot 2022-03-17 at 01.06.53@2x.png
The idea is straightforward we send dynamic data from Appsmith onto the HTML template using a webhook, and APITemplate will generate a PDF file from the HTML.

Here’s how the HTML is added:

CleanShot 2022-03-17 at 01.08.52@2x.png

The item variable here holds all the data that will be updated from the webhook request on Appsmith.

We don't see any data here, as we did not have any workflow. So let's create on n8n!

Creating a Workflow on n8n

n8n: n8n helps you to interconnect every app with an API in the world with each other to share and manipulate its data without a single line of code. It is an easy-to-use, user-friendly, and highly customizable service, which uses an intuitive user interface for you to design your unique workflows very fast.

I'll be using the cloud version of n8n for this tutorial. Note that you can also self-host n8n on your server.

Now, let's create the workflow:

  • Drag and drop a webhook node and add the following configuration:
  • Set the authentication type to None.
  • The HTTP method to POST.
  • Set the Response method to Using 'Respond to Webhook' node

Now copy the TEST URL, and create a new API on the Appsmith app by clicking on the + icon next to Queries and pasting the TEST URL in the request URL. Rename the query to generatePDF for a better naming convention.

Now navigate to the Body tab in the API request and paste the following JSON:


{
    items:{{Table1.tableData}}
}


Here, we send the items data from the Table to the webhook using the moustache bindings.

Now, we can test this webhook by starting the workflow; here’s how it works:

Next, drag and drop a new APITemplate.io node and connect it to the webhook and use the following configuration:

  • First, copy the API key to the Credentials for APITemplate.io property.
  • Set resource to PDF and Operation to Creation
  • The template ID property can be found under the manage templates tab; this refers to the template created in the last section.
  • Toggle the JSON parameters and Download to ON
  • Copy the following in the Properties:
{    
    "items": {{(JSON.stringify($node["Webhook"].json["body"]["items"]))}}
}


This is where n8n sends data from Appsmith to APITemplate using a webhook.

Now, connect a new Respond to webhook node and set its respond with property to First incoming item property. This is how the complete workflow looks like:

CleanShot 2022-03-17 at 02.02.07@2x.png

Now click on execute the workflow and RUN the API on Appsmith; we should see a response with a downloadable PDF URL:

CleanShot 2022-03-17 at 02.13.55@2x.png

To improve the look and feel, we could create a new button and set its onClick property to run generatePDF query and bind the response to a text widget.

Here’s the complete workflow:

Alternatively, for PDF generation on Appsmith, we could also rely on other services like Zapier / Adobe.

If you’re interested in using a database not listed on our website as an integration, please let us know about it by raising a PR on Github, and we will do our best to include it at the earliest.

Join our growing community on Discord, and follow us on Youtube and Twitter to stay up to date.

Build a CRUD App with a Redshift Database
1
March
2022
Resources

Build a CRUD App with a Redshift Database

Build a CRUD App with a Redshift Database
Vihar Kurama
0
 minutes ↗
#
admin
#
ui
#
mysql
#
app-development
#
guide
Resources

Amazon Redshift is a fast, fully managed, petabyte-scale data warehouse service [A data warehouse is a type of data management system that is designed to enable and support business intelligence (BI) activities, especially analytics.]. It makes it easy to manage your data warehouse and automatically distributes your data across multiple nodes to eliminate hot spots and provide high availability. It’s also an excellent option for building a frontend. However, it does have a few specifics that might make you rethink your current strategy. However, with Appsmith, it’s possible to create a fully functional and custom frontend in minutes. A vast array of pre-built UI components that is widgets are available to help you build good-looking applications. Connecting data sources with Appsmith takes a few minutes, and you can quickly build tools on top of the database of your choice.

This blog will teach you how to build a frontend that can connect to Redshift as a datasource.

Connecting Redshift on Appsmith

On Appsmith, it’s pretty straightforward to establish a connection with any datasource, including Redshift. We need to make the connection to the endpoint, database name, and user credentials. With this in mind, let’s get started.

  • Create a new account on Appsmith (it’s free!), if you are an existing user, log in to your Appsmith account.
  • Create a new application under the dashboard under your preferred organization.
  • On your Appsmith application, click on the + icon next to Datasources on the left navigation bar under Page1
  • Next, click on the Now, navigate to the Create New tab and choose Redshift datasource; you’ll see the following screenshot:
CleanShot 2022-02-22 at 13.51.39@2x.png
  • All these details can be found under the configuration settings when using Redshift on a hosted service.

Note: I’m using a free Redshift account on Amazon Web Services (AWS) in this example.

CleanShot 2022-02-22 at 13.52.25@2x.png
  • Rename the Datasource to Redshift CRUD by double-clicking on the existing one.

Here’s what the configuration would look like:

CleanShot 2022-02-22 at 14.23.12@2x.png
  • Next, click on the Test button at the bottom right of the screen. This will help you with understanding whether your configuration is valid or not. Hit the ‘Save’ button to establish a secure connection between Appsmith and Redshift if it returns a successful message.

Using Redshift’s Seed Data

The basic configuration is complete, so now, we will now use the seed data already loaded on the Redshift Data (TICKIT data).

Note: After the connection is established, we can see all the (tables) under the connected datasource.

CleanShot 2022-02-22 at 14.26.50@2x.png

Now, let’s use the Category table to build our CRUD APP!

CRUD on Redshift with Appsmith

Implementing the Read Operation

First, let’s read our data from the database and display it on a beautiful table widget. Follow the below steps:

  • Click on the + icon next to the datasources and click on create New + from the Redshift CRUD datasource.
  • Rename the query to getCategories
  • Copy the following SQL script to query all the Categories from the category table:


SELECT * FROM public."category" LIMIT 10;


  • This simple query returns all the category details present in the sample data item. Hit the RUN button to view all the results.
CleanShot 2022-02-22 at 15.07.07@2x.png

We now have our query; let's bind this onto the table widget; for this, follow the below steps:

  • Click the + icon next to widgets on the sidebar, search for the table widget, and drag and drop it onto the canvas.
  • You can make any configurations to any widget via the property pane. Click on the table widget on the canvas; you will see the property pane docked to the sidebar on the right. Now, under the Table Data property, use the moustache syntax to bind the query:
{{getCategories.data}}


With this, we should see all the data displayed on the table. The column names can be configured and re-organized under the property pane.

CleanShot 2022-02-22 at 15.07.42@2x.png
Implementing the Create Operation

To add the create operation on Redshift, let’s make UI.

  • Drag and drop a button widget onto the canvas. Open its property pane, set the onClick property to Open a New Modal, and choose Create New.
  • This will open up a new modal now; let’s drag and drop a few widgets to create a form that we can use to add new Categories into our database.
CleanShot 2022-02-22 at 15.09.07@2x.png

Here, we have three input widgets to add to our category. We can configure the default values, labels, and placeholders by selecting the respective property panes. Now, let’s write the query to create a new category on Redshift.

Follow the steps below:

  • Click on the + icon next to the datasources and choose to Create New + from the Redshift CRUD datasource
  • Rename the query to addCategory
  • Copy the following SQL script:
INSERT INTO public."category" ("catgroup", "catname", "catdesc")  VALUES ('{{Input1.text}}', '{{Input2.text}}', '{{Input3.text}}');


CleanShot 2022-02-22 at 15.10.54@2x.png
Implementing the Update Operation

The Update operation is quite similar to the create operation. First, let’s build UI by creating a new custom column on the table by clicking on ADD A NEW COLUMN under the columns property.

Now, rename the column to Edit Category, and click on the cog icon next to it, to configure column settings. Under this, we’ll see column-type properties set to a Button type. A modal should open up with the necessary fields to update the item when clicked.

Now, copy-paste Modal1, rename it to Modal2 and set the onClick property of the Edit Category button to open Modal2. Here, in the form, we can set the default value to show existing information; to display this, use the selectedRow property from the table widget.

CleanShot 2022-02-22 at 15.15.53@2x.png

Let’s write the Edit query using SQL:

  • Click on the + icon next to the datasources and choose to Create New + from the Redshift CRUD datasource
  • Rename the query to editCategory
  • Copy the following SQL script:

UPDATE public."category" SET
    "catgroup" = '{{Input1Copy.text}}'
    "catname" = '{{Input2Copy.text}}'
    "catdesc" = '{{Input3Copy.text}}'
  WHERE "catid" = {{Table1.selectedRow.catid}};

Here, we have an edit query that collects all the data from the form widgets on Modal2. Note that we use the mustache syntax to bind the data from the widgets onto the query body.

We’ll now need to configure the submit button; for this, go back to Modal2 and set the button’s onClick property to execute a query and choose **_editCategory_** under the events property:

Implementing the Delete Operation

The delete operation is pretty straightforward with the Table’s selectedRow property; before we dive into it, let’s create a new column on the table and set it to the button. For this:

  • Create a new custom column on the table by clicking on Add a New Column under the columns property.
  • Now, rename this column to ‘Delete Category,’ and click on the cog icon next to it, to configure column settings. Under this, we’ll see column-type properties set to a button type.

Now, let’s write the Delete query using SQL:

  • Click on the + icon next to the data sources and choose the Create New + from the Redshift CRUD datasource
  • Rename the query to deleteCategory
  • Copy the following SQL script:
DELETE FROM public."category"  
    WHERE catid = {{Table1.selectedRow.catid}};


Set the Delete Category button’s onClick property to run the deleteCategory query.

With these four operations configured, you will be able to read and analyze information from your database, edit the data, add or delete information and update records.

If you’re interested in using a database not listed on our website as an integration, please let us know about it by raising a PR on Github, and we will do our best to include it at the earliest.

Join our growing community on Discord, and follow us on Youtube and Twitter to stay up to date.

October Roundup: Widget Improvements, New Appsmith functions, and ARM Architecture Support
2
November
2021
Monthly Round-up

October Roundup: Widget Improvements, New Appsmith functions, and ARM Architecture Support

October Roundup: Widget Improvements, New Appsmith functions, and ARM Architecture Support
Vihar Kurama
0
 minutes ↗
#
announcement
#
applications
#
app-development
#
community
#
crud
Monthly Round-up

We’re back again this month with updates from the last 30 days. We like to work hard! We’ve shipped many features, fixed bugs, and launched Hacktoberfest with a series of fun events. You can check them out here.

Widget, UI, and UX Improvements

#1 Menu Buttons on Table Widget 

Tables on Appsmith are one of the most loved widgets, and yes, we’ve upgraded them again! We can use menu buttons inside the table widget on any particular column to create menus and customize them. Open the column settings from the table’s property pane and set the column type to the menu button to see them in action! And just like that, we should be able to see a menu button on our table. Additionally, you can add more items to this by configuring the Menu Items property. That’s not all, and you can further customize the items to have icons, border radius, box shadows, and more!

#2 A New Sparkling White UI

Notice anything new? Yes, we have improved our whole design system to help developers focus more on their application editing on Appsmith. Right from searching through apps on the dashboard to building them using queries and widgets, everything is white! 

#3 Option to Hide/Unhide Properties from Property Pane

At Appsmith, we consistently focus on adding new properties and features to widgets, and sometimes it can get a bit overwhelming to see all of these at the same time! To make it less cumbersome, we’ve added an option to hide and unhide a few properties. Developers can concentrate on what’s important. To use this feature, toggle the dropdown arrow inside the property pane. You will see an option to collapse the various options within the pane. For example, in the picture below, only the header option has been made visible.

New Appsmith Functions!

You can bid goodbye to refresh buttons! Developers had to use refresh buttons on Appsmith Appsmith to be able tore-run the queries. We recognized this pain point. Now there’s a cool new feature to periodically run APIs and DB queries. You can configure these by using the  setInterval and clearInterval functions!

The setInterval function executes a trigger callback at a given interval. Here’s how you can use it while dynamically binding queries onto widgets:

setInterval(callbackFunction: Function, interval: number, id?: string)
// setInterval(() => { Query1.run() }, 10000, "myTimer");

The clearInterval function stops executing the trigger callback started with the setInterval method.

clearInterval(id: string)// clearInterval("myTimer");

Appsmith Deployments

#1 Helm Chart Support

Helm charts are now added for Appsmith deployments on Kubernetes deployments. These include application deployments with basic default support. Additionally, developers can add custom configuration for persistent volume data, custom ingress controller and secure with TLS certificate

#2 Support for Deploying Appsmith on ARM Architecture 

Previously, many developers had reported issues regarding docker-based installation of Appsmith on ARM architectures. Now, we had rectified them and had added extensive support for M1 MacBook users.  Following are the changes that we made to the scripts for docker installation:

  • We heavily refactored Dockerfile to build the image that is able to support both AMD64 and ARM64 architecture
  • We have updated docker.env.sh with additional environment variables and renamed the existing MongoDB credential variables
  • We added a document to build an image for multiple architectures using Docker buildx

Quit Buggin! Cheers to our Updated Debugging Experience

We have improved the debugging experience by adding hint and errors messages for different cases when working on queries and binding them onto widgets. To make these messages more efficient, we added a new attribute named readableError to the ActionExecutionResult object, returned to the client post after actions are executed. With this, we should be able to understand and solve complex errors quickly. Not just that, we have seen many APIs failing because of using duplicate headers or query parameters, so we have added a few hint messages to help you debug faster.


We’ve got a host of other bug fixes and updates too, be sure to check out our release notes here

See you next month with more updates! Do follow us on Twitter, Youtube, and Linkedin to stay up to date.  

Our New JS Snippets Feature Helps You Write JavaScript in the Appsmith Platform
18
October
2021
Announcement

Our New JS Snippets Feature Helps You Write JavaScript in the Appsmith Platform

Our New JS Snippets Feature Helps You Write JavaScript in the Appsmith Platform
Vihar Kurama
0
 minutes ↗
#
announcement
#
beginners
#
applications
#
app-development
#
features
Announcement

Building an app on Appsmith is great fun. Why? Because it takes minutes to build a clean and consistent UI, and less than a few hours to make data connections.  We might be tooting our own horn, but what we love about Appsmith (ask our in house devs!) is that we can use JavaScript anywhere on the platform to add additional transformations, functionalities, and actions using the moustache syntax. We’re aware that not everyone is a JavaScript enthusiast, everyone prefers a language of their choice! So we’ve come up with our new feature: “JS Snippets.” With this, you can get some help with writing JavaScript inside Appsmith. In this blog, I will tell you how we made this feature and how you can use it!

The story!

We often see many questions in our community forums and discord channels seeking help with binding nested APIs, write data transformations, configure chained actions. Hence, we thought of building a library of snippets inside Appsmith applications that you can use directly and customize based on your data source. 

Initially, we thought of the issue in a straightforward way, but at Appsmith, we always like to go the extra mile. So, we brainstormed this idea multiple times and decided to extend it to customize and add snippets particular to widgets and data sources. But, in order to do this kind of customization, we need a database application that validates and filters these snippets. So we built an internal Appsmith app that manages all the JS Snippets. This is how the application looks like:

Here, as we can see, on the left, we see a list of all the available snippets today. When these are clicked, we will see the details of the snippet and have options to verify it and publish it live directly to the JS Snippets library.

To customise these snippets, we define three formats for each of them. 

  1. Snippet: The example code snippet written in JS
  2. Args: Customisable variables inside the snippets and their expected data type,
  3. Template: The dynamic template that helps devs customise their snippet with any variable on Appsmith

Here’s an example of how we ideated customizable JS snippet using these three forms for merging two queries in a table:

Snippet:

{{ 
	fetchOrders.data.map((orderObj) => {
   const user = fetchUsers.data.find((userObj) => userObj.id == orderObj.refId) || {};
   return { ...orderObj, ...user };
	})
	}
}

Args:

[
  {
    "identifier": "fetchOrders",
    "name": "Query1",
    "type": "OBJECT"
  },
  {
    "identifier": "fetchUsers",
    "name": "Query2",
    "type": "OBJECT"
  },
  {
    "identifier": "orderObj",
    "name": "row1",
    "placeholder": true,
    "type": "OBJECT"
  },
  {
    "identifier": "userObj",
    "name": "row2",
    "placeholder": true,
    "type": "OBJECT"
  },
  {
    "identifier": "id",
    "name": "key1",
    "type": "VAR"
  },
  {
    "identifier": "refId",
    "name": "key2",
    "type": "VAR"
  },
  {
    "identifier": "user",
    "name": "recordForMerge",
    "placeholder": true,
    "type": "VAR"
  }
]

Here’s a screenshot of how the snippet is rendered on Appsmith:

Users can now directly copy this snippet onto the widget, or customize the arguments, test it out, and use it in the widget.

How to use JS Snippets on Appsmith

We can find JS snippets inside the Appsmith applications from Omnibar. Click on the Search/Omnibar from the top navigation and choose the `Use snippets` option. Here, you can filter snippets based on data sources and UI widgets. 

The other easy way is to access snippets from the slash commands. Just type in / inside the bindings, and choose the insert snippet option. 

Special credits to Arun Vijayan, Sumit Kumar, Ajinkya, and Nikhil Nandagopal who had worked so hard on this feature!

Hope you’ll build some super cool applications using the JS Snippets on Appsmith! If you do, don’t forget to tell us about it, we would love to feature your work! Your contributions and feedback help us make Appsmith better and we really appreciate it.

Join the community! Come chat with us on Discord, or jump in on Github directly!

You can also follow us on Twitter and Linkedin.

Build a GitHub Dashboard and Track Any Open Source Project
10
August
2021

Build a GitHub Dashboard and Track Any Open Source Project

Build a GitHub Dashboard and Track Any Open Source Project
Vishnupriya Bhandaram
0
 minutes ↗
#
github
#
open-source
#
app-development
#
ui
#
javascript

Did you know that Appsmith is a fully remote distributed organization? We have colleagues in 5 countries! This makes total sense for us as an open-source platform with contributors from over 100 countries (take a look at our activity on Github). It’s also why we think of ourselves as learners; we read, talk to people, and love feedback. And in that spirit, every new team member makes an app on Appsmith in their first week upon joining us! And there is only one rule, that there are no rules! These apps range from functional to fun to downright silly!

This week, we’re featuring our colleague, Favour Ohanekwu’s app. Favour is a front-end engineer from Ibadan in Nigeria. Over the years, he has been actively involved in building web applications across several industries ranging from health, agriculture, and IoT. You can follow his work here.

First steps

Favour toyed around with a few ideas before landing on a final app idea. Some of these app ideas were:

  • An application that allows employees to review their team members and view reviews about them from their fellow team members.
  • An application that shows the current availability status of each employee at any time of the day. On this application, employees will be able to set their status (Active, Busy, Away) and be able to see the current working status of other team members.
  • A dashboard that reports the company's GitHub repositories and compares them in terms of several metrics.

Favour chose to work on the third idea to build a Github Dashboard to view and track several projects, using Github’s REST API.

Click here to see the app!

We’ll outline the steps involved in making this app, and you’ll see how easy it is to build this application in few simple steps using Appsmith!

Getting Started

This short tutorial uses the cloud version of Appsmith. However, you can always export and import Appsmith apps to different environments (cloud, self-hosted, local). The recommended way to use Appsmith is to use Docker; follow the documentation here for detailed instructions if you want to build locally.

  1. Create a new account or sign in with an existing account, redirecting it to our dashboard.
  2. Click on Create New under your organization, and this will create a new Appsmith application.
  3. Rename the application to GitHub Organisation Dashboard (or any name you’d like) by simply double-clicking on the existing one.
  4. On the left, find the entity explorer; this is where you can manage all the widgets and data sources of the entire application.

Now you can build a simple UI with Appsmith widgets to build the dashboard and display all metrics crucial to your project!

Fetching Data from Github Organisation

Now that you’ve configured the app, you will need to configure a data source that will fetch all the repos from a Github organization. To do this, follow the steps below:

  • Click on the + icon next to the Widgets, find the input widget, and drag and drop it on canvas. The idea is to enter the organization name and dynamically fetch all the repos created under that organization.
  • Next, click on the + icon next to Data Sources, and create a new API as a data source. Rename the API as get_organization_repos and paste the following in the URL:
https://api.github.com/orgs/{{Input1.text}}/repos
  • Here as you can see, we’re dynamically passing the organization name to the GitHub API from the input widget.
  • Go back to the canvas, and drag and drop a new Select widget; now paste the following snippet to pollute the options with repos in the select widget from the API.
    {{
    get_organization_repos.data.map((repo)=>     ({
        "label":repo.name,
        "value": repo.name
    }))
    }}
  • Drag and drop a new button widget and set the onClick action to Execute a Query and select the get_organization_repos
  • With this, whenever you enter a new organization name, the select widget automatically populates it with all the repos from that organization.

Additionally, you can drag text widgets and add some context regarding the same for the dashboard. Here’s how it looks:

Screenshot 2021-08-10 at 11.10.52 PM.png

Fhere

Fetching Data and Events of a Particular Repository

Displaying Core Metrics

Now that the repositories are listed on the application, you can fetch the data of a single repository and display all the crucial information such as network count, forks, subscribers, and a few more.

  • Click on the + icon next to the Data Sources and add a new API and set the URL to the following:

https://api.github.com/repos/{{Input1.text}}/{{home_select_repo.selectedOptionValue
  • This URL will fetch the repo details; we’ll name it as get_organization_repo_details
  • Similarly, add one more API data source and name it as get_repo_events with the following URL:
https://api.github.com/repos/{{Input1.text}}/{{home_select_repo.selectedOptionValue}}/events
  • For both of these data sources, we send the repo name from the Select widget, which is named as home_select_repo, and the selectedOptionValue property will help access the selected option from it. You need to create a UI for displaying all the core repositories based on the selected option. For this, drag and drop a few text widgets onto the canvas, and set the Value property to the following:
TextWidget1 Value: {{get_organization_repo_details.data.network_count}}
TextWidget2 Value: {{get_organization_repo_details.data.forks_count}}
TextWidget3 Value: {{Get_organization_repo_details.data.subscribers_count || "-"}}
TextWidget4 Value: {{Get_organization_repo_details.data.open_issues_count }}
TextWidget5 Value: {{Get_organization_repo_details.data.watchers_count}}

Additionally, you can add more text widgets and a container widget to organize this more beautifully.

Here’s how Favour did it:

Screenshot 2021-08-10 at 11.11.47 PM.png

Displaying Repository Events

In this section, you can display a table widget to show all the events for a repository. In this way, you can monitor who is creating pull requests, pushing new changes, etc.

Follow the steps below to do this:

  • Drag and drop a new table widget onto the canvas.
  • Open the property pane of the table widget, and set the following in the Table Data property.
{{
        get_repo_events.data.map(event => ({
            "Date": moment(event.created_at).format("LLL"),
            "Type": event.type.match(/[A-Z][a-z]+/g).join(" "),
            "Actor": event.actor.login,
            "Avatar": event.actor.avatar_url,
            "View": event.actor.url
        }))
   }}

With this code snippet, you can display all the data from the get_repo_events API and bind it on the table widget. Following is how the output looks like:

Screenshot 2021-08-10 at 11.13.25 PM.png

Displaying Statistics

Last, you can add a couple of charts that will help you visualize the number of repository forks and the number of watchers for the repository by following the below steps:

  • Drag and drop a chart widget onto the canvas.
  • Set the title to Number of Repository Forks
  • Choose the Pie Chart under the Chart Type property.
  • Now create a new series and set the title as Repository Forks and add the following under `Series Data
{{
Get_organization_repos.data.map(repo=>({
  "x": repo.name,
  "y": repo.watchers
}))
}}
  • Similarly, add more chart widgets, set the chart type to Bar Chart, and set the Series Data to the following:
{{
Get_organization_repos.data.map(repo=>({
  "x": repo.name,
  "y": repo.watchers
}))

Following is a screenshot:

Screenshot 2021-08-10 at 11.14.50 PM.png

Now, wasn’t that easy to do with Appsmith?

Have you made something using Appsmith? Write to me (vishnupriya@appsmith.com), and I would love to feature you on our blog!

If you’re interested in building an app on Appsmith, sign up today. We have docs, and tutorials and live help, and a vibrant discord community to help you along the way. So go ahead, put your ideas out there!

Do you want to join Appsmith? We’ve got a bunch of openings; take a look here and apply!

Don’t forget to join our community and sign up for live events.

Appsmith Round-Up: Three New Widgets, Slash Commands, and Improved Navigation
18
August
2021
Monthly Round-up

Appsmith Round-Up: Three New Widgets, Slash Commands, and Improved Navigation

Appsmith Round-Up: Three New Widgets, Slash Commands, and Improved Navigation
Vihar Kurama
0
 minutes ↗
#
community
#
open-source
#
javascript
#
app-development
Monthly Round-up

One of the key beliefs here at Appsmith is to make our framework better each and every day. Our engineering and design teams are constantly aiming to expand possibilities for all users on Appsmith. Our speed of shipping is something we’re proud of, and we hope to keep this momentum going for the days to come.

July and early August were busy months at Appsmith as we shipped so many new features — especially widgets, and an improved navigation experience. In this round-up, we will take you through some of the significant changes and improvements that we brought in over the last 30 days!

🎨 New Widgets and Upgrades

One of the primary goals of our design and engineering is to ship new widgets as early as possible. Widgets help our users put together UI components quickly, and speed up the overall app-making process. Now, we’ve added three new widgets! The Rating, Divider and Menu widgets. Here’s what each widget does:

Rating-Widget: With this widget, users can perform a quick rating operation on anything! For example, in a support dashboard, you can use the Rating widget to rate conversations with your customers. Not just that, at Appsmith, we’re quite serious about this customization. This widget goes beyond appearances; extended features of this widget include colours, calling APIs, viewing alerts etc.

Drag and drop the widget onto the canvas, and use the property pane to assign actions.

Divider Widget: The divider widget on Appsmith can help visually separate or compartmentalize different parts of an application. This can be added anywhere around the canvas, either in a horizontal or vertical orientation. You can always customize the divider type and change accents based on the application's aesthetics.

Menu Widget: This widget was highly requested by the community. With this widget, users can create and customize menus on Appsmith. Additionally, users can also add different functions such as filtering data based on the selected item on the menu or navigating between any pages.

We also made some much-needed improvements to the existing widgets! Here are some of the notable changes:

  • The list widget is now faster, smoother, and bug-free. Users can now increase the height of list items, use modals, add multiple bindings, and do much more! Read the documentation to learn more.
  • The image widget now has a cool rotate property! To enable it, toggle the rotate property on the property pane. Wait! We’ve also added a new object-fit property that lets users align images to cover, contain or auto-fit! Cool right?

When using filters on the Table widget, users can now drag the filter pane with ease anywhere across the canvas. This helps users look at other widgets on the canvas easily.

We’ve seen many people adding data related to expenses, hence to make it easier we’ve added a currency data type on the input widget to help with money calculations. Users can also set the currency type and the decimal correction for more accuracy.

The table widget is a user favourite and with good reason. There are many things a Table widget does best. So, we are thinking up ways to improve its functionalities. Now, users only view a few headers on the table widget or remove them to show the data. They can export the entire table data into an excel file or CSV file with just one click. To make it more powerful, we’ve added a feature where users can select multiple rows on a table. To enable this, choose the multi-select property from the table widget property pane.

🛩️ New Navigation and Slash Commands

Last month, we spent a lot of time upgrading our user experience for creating and connecting data sources to applications. This was one of the crucial design decisions we've taken so far! With this new upgrade, users can now create and manage their data sources much faster. To learn more about our design and engineering approach, read the detailed blog post here.

Simply put, our overarching goal with this update was to get people to connect their data to the UI.

Widget ➡️ Datasources ➡️ Querying Data ➡️ Connecting Widget

With this flow in mind, we made several changes to the navigation experience.

Users can now:

  • Connect data sources faster
  • Find the right widget for available data
  • See relationships between UI and Data clearly

Slash Commands

We introduced another big feature. Appsmith now has slash commands. Slash Commands are a quicker and simpler way to bind widgets to a data source. Now users can trigger commands by typing "/," which can be utilized anywhere inside a dynamic binding.

New Context Menu

We focused on making the widget grouping experience much better. We know how valuable this feature is for our users, especially in terms of the overall experience of Appsmith. Users can now drag over particular widgets and group them together, a context menu will help in performing different actions like duplicating/copying/deleting within a single click.

⚒️ New Integrations

It’s now pretty well documented that Appsmith is all about integrations. We have included yet another database integration to Appsmith. We’ve made it super easy to build new integrations on Appsmith. This is because we've architectured each integration as an individual module. It's super handy for us and contributors to build, customize and organize any new integration. Now users can integrate with ArangoDB! ArangoDB is an open-source multi-model database system where you can natively store data for graph, document and search needs. And the best part? It’s free!

This integration feature was developed by mingfang, one of our users and top contributors on Github!


That’s all we have for this month’s round-up. Follow us on Twitter and Linkedin to stay up to date with more news and announcements!

We love feedback, and we want to know your thoughts. Write to us with your ideas, opinions, or even send us brickbats on marketing@appsmith.com.

If you want to write a blog for us, send me an email and I’ll make it happen: vihar@appsmtih.com.

Test and Deploy your APIs Using These Open Source Tools
28
July
2021
Resources

Test and Deploy your APIs Using These Open Source Tools

Test and Deploy your APIs Using These Open Source Tools
Vyom Srivastava
0
 minutes ↗
#
apis
#
open-source
#
testing
#
app-development
Resources

Testing an API is one of the most important phases of the API development lifecycle. It ensures that the API you’re deploying on the server is bug-free and highly optimized. But the testing phase can be very complex as it involves different types of testing, such as load testing, regression testing, security testing, etc. There are a lot of challenges developers and testing teams face during the testing of API. Let's discuss them first:

Why is API Testing a Difficult Task?

We all know that APIs involve a lot of modules that have a lot of functionalities. Let’s take a simple example of an e-commerce application. You’re going to have many endpoints such as /login, /logout, /cart, /wishlist, /profile, and so on. You need to ensure that each endpoint is delivering what it is supposed to. For example, /cart should only show products associated with a particular profile and shouldn’t mix with other products.

An application like the one mentioned above can have about 300-400 endpoints or sometimes even more! On top of that, you need to make sure that the validations are working fine, response time is low or at least optimized, there’s no bug in the API, and good performance even when 1000s of requests are being made simultaneously. You also need to ensure that the API returns an appropriate status code such as 20x, 40x, 50x, etc. All this makes API testing not only tricky but also a time-consuming task.

To reduce the complexity of the whole testing and deployment process of the API, there are a lot of open-source tools available on the internet (if you prefer non-open-source tools, you can check out Postman or Firecamp ). These tools not only save a lot of time but also give you insights like the response time of the API, among others.

Once you’re done with testing, you can deploy the API on a server. Deployment is the process where you’re ready to go live with the API and need to move it to the live server. Every time you make a change to the API, you need to redeploy the API on the server (after testing, obviously! 😬)

Here's our list of open source tools that you can use to test and deploy your API:

SoapUI

Screen Shot 2021-07-27 at 10.54.02 PM.png

SoapUI is another API tool that allows you to test and deploy your APIs. This is one of the most matured and trusted API testing tools. One of the unique features of this tool is, it supports SOAP APIs too. The tool is mainly used for QA and API testing. It also allows you to connect external data sheets to retrieve data for executions.

Soap UI also allows you to send multiple API requests; triggering a single test case and supports a wide variety of testing such as load testing, functional testing, security testing, etc.

Pros

  • Easy to define variables and pass them in parameters.
  • Support for SOAP API

Cons

  • Slower to perform tests on complex APIs
  • Not completely free
  • UI takes a little bit of getting used to

Apache Jmeter

Screen Shot 2021-07-27 at 10.58.03 PM.png

Apache Jmeter is an open-source testing tool that not only tests APIs but scripts too. You can create your own test cases, and it’ll perform different types of testing like module testing, regression testing, etc.

The UI is quite simple and easy to use. You can test the APIs in two ways: either use direct API requests or write a code to make the requests to an API endpoint. The tool is entirely written in Java and supports multiple languages such as Python, C, Java, etc.

It also comes with a marketplace where you can just download the plugins to expand the platform’s functionalities. It supports multiple protocols such as FTP, HTTP, LDAP, SOAP, etc. JMeter also supports graphs and charts, so the results can be visualized easily. To perform UI testing, you can run Selenium test cases as well.

Pros

  • Free to use and completely open source
  • Can be connected to third party platforms like Jenkins
  • Can be scaled easily
  • Marketplace is a unique feature

Cons

  • Very slow
  • UI is dated

Hoppscotch

Screen Shot 2021-07-27 at 10.59.48 PM.png

Hoppscotch, previously known as Postwoman, is another popular open-source API development and testing platform. It has a dark UI and a minimalistic design scheme. It is one of the fastest API testing tools allowing you to send requests and copy responses in real-time.

It comes with a variety of themes and you can even install it as a PWA (Progressive Web App) on your mobile device. The tool also lets you make a full-duplex communication channel over a single TCP, in other words you can make Websocket connections. Another big feature of this tool is that you can also test GraphQL queries.

Pros

  • Support for Websocket
  • PWA
  • Easily create documentation

Cons

  • Comes in web variant only
  • It doesn’t support testing like regression, load, etc

Karate

Screen Shot 2021-07-27 at 11.07.24 PM.png

This platform has been developed by Intuit and is used for multiple purposes like API testing, deployment, creating mock test servers, web browser automation, etc. It is written in Java but doesn’t require the end-users to write anything in Java. It’s so easy to use that even non-programmers can write the test cases. It supports YAML as andV, so you can easily use them to write data drives tests. You can also perform cross-browser-based Web UI testing.

Pros

  • Support for multiple testing
  • Includes a lot of functionalities

Cons

  • It doesn’t have a great UI so you might have to write a lot of code

Insomnia

Screen Shot 2021-07-27 at 11.08.14 PM.png

Insomnia is another open-source tool that lets you track the development and deployment of API endpoints very easily. It uses a Swagger-inspired editor, so if you’re familiar with it you’ll be able to easily use this tool.

It allows you to import API specs from OpenSpec API as well as Postman. It also comes with a CLI tool called Inso, which lets you go in-depth with the API testing. You can also connect version control software like GitHub, Bitbucket, SVN, etc.

Pros

  • Support for .env files
  • Support for Gitsync

Cons

  • Process to test the API is a bit lengthy

What’s Next?

Now that you’re equipped with your APIs, you can use Appsmith to create full-fledged applications by connecting your data to our extensive repository of pre-built UI widgets like forms, buttons, lists, maps and so much more. And since Appsmith is a GUI based platform, you can drag and drop these widgets to create your applications. You can also invite your colleagues to collaborate with them and then deploy it to be shared with internal or external users.

Psst! You can connect your data on Appsmith either through APIs or through our native integrations with popular databases like Postgres, MongoDB, and Snowflake, among others, as well as apps like Google Sheets!

610002bbe68fa271933cee6e_ABK8x87Kne_y4oROzmhaoMwpShsXIcXMr_VubVdsoztQaUGrIxFdgKnwTNUm_Pb4vEDGDNjuVk1t0UgKWrOWSKaZ5pF1HIWNdqm4kqNg6_nPuTZTgaXEAJepVbZKRuW3SHAdmi4u.png

Also, by running CURL commands directly on the platform, you can test and deploy your apps easily and quickly.

Are you interested in building something with Appsmith? Take it for a spin. Join our vibrant community on Discord. To get regular updates on what we’re up to, follow us on Twitter!

Appsmith Roundup: Build CRUD Apps with one-click, Move Multiple Widgets, New Icon Widget and Omnibar
7
September
2021
Monthly Round-up

Appsmith Roundup: Build CRUD Apps with one-click, Move Multiple Widgets, New Icon Widget and Omnibar

Appsmith Roundup: Build CRUD Apps with one-click, Move Multiple Widgets, New Icon Widget and Omnibar
Vihar Kurama
0
 minutes ↗
#
open-source
#
community
#
app-development
#
javascript
#
ui
Monthly Round-up

We’re back again this month with updates from the last 30 days. Apart from adding support to self-hosted Appsmith instances, we’ve got some big features we shipped last month.

Here’s a low-down on what we were up to!

🖱️ Generate a CRUD app from any database with one click!

We know how important CRUD applications are for internal operations. Why should something so critical to an organization's success be difficult to make? We’ve made it super easy to make one. What if we said that you can now make the entire CRUD application with all the UI, logic, and complete control in just one click? Now, it’s possible.

We’re super excited to announce our new feature called the “Generate New Page from Database” With this, you can build CRUD applications within no time. To learn more about this feature check out this blog here or watch a quick demo here.

Want to create your own CRUD app on Appsmith, here’s how you can do it:

If you’re new to Appsmith follow the steps below:

  1. If you’re an existing user sign in to your account or you can sign-up here for free.
  2. After you sign in you’ll be redirected to the Appsmith dashboard where you can create a new application by clicking on the Create New button.
  3. This will create a new Appsmith application, now to connect a data source click on the + icon next to the Datasource option on the left navigation bar.
  4. You can choose from a wide range of options here, in case if you want to test it you can use the mock-users database.
  5. Next, under the active data sources click on the GENERATE NEW PAGE option.

You’ll see the following options:

sdHNRHrKK.png

Now, you can select the table and add a searchable column. As soon you click on the Generate Page, you’ll see the UI where all the CRUD operations can be performed.

Hola, and with just one click the entire application is generated!

🎉 New ICON Widget

Icons are a great way to create a better user experience! On Appsmith, buttons are widely used for performing different actions such as calling APIs, opening modals, showing alerts, and many more. Sometimes, it might be hard to find the right buttons; in such cases, our new icon widgets come in handy. You can use it to create a better user experience or perform actions similar to the button widget.

We ship this icon widget with a wide range of customization, and you can choose these from 300+ icons or connect with your own. Like other widgets on Appsmith, we've added buttons like button style, button variant, border radius, box-shadow, and shadow colour to help you create the perfect application!

Here's a sneak peek of some of the variants created using the icon widget.

Awesome right? What are you waiting for? Give it a try!

New Omnibar

When building huge internal applications on Appsmith, sometimes it’s hard to navigate to the right widget or data source queries, to overcome this, we’ve redesigned our entire Omnibar. With this, you can navigate to any widget, or data source query at any point of time with a single click, not just that, you can search for any query from our documentation directly from inside the application using Omnibar, all you’ll need to do is use the keyboard shortcut CMD + K or CTRL + K and enter your query!

💡 Moving multiple widgets using widget grouping!

So far, we’ve made quite good progress with our widget grouping feature. With this, developers are able to copy and delete multiple widgets at a time. Now, we’ve added the most requested feature! Yes, it’s moving multiple widget’s when widgets are grouped. Just, select the required widgets by dragging them over them and move across the canvas to multiple widgets at one time! Cool right? You can also use this to move widget’s into containers as well. Here’s the GIF showing the same:

We’ve got a host of other bug fixes and updates too, be sure to check out our release notes here.

Build a Custom Application using Slack API
10
August
2021
Tutorial

Build a Custom Application using Slack API

Build a Custom Application using Slack API
Vishnupriya Bhandaram
0
 minutes ↗
#
open-source
#
applications
#
slack
#
app-development
#
javascript
Tutorial

I recently joined Appsmith, and I am one of the few non-technical employees here! And as part of the onboarding process, all new team members have to build an app on Appsmith! It doesn’t matter if you’ve studied journalism and anthropology, have no experience in coding or JavaScript, no excuses! The brief was that it could be fun or functional, and anything under the Sun! Anxiety and panic were having a field day while I thought about what to build and where to start and finally decided on making something fun yet functional for Appsmith.

We have a vibrant channel on Slack called the #reading-club, where channel members can share and discuss books they have read. I expect (and hope) that this channel will have a high volume of messages, and the members are likely to grow. Even though there are only 26 members in the channel right now, one has to scroll up to get to earlier recommendations! It can be pretty frustrating to do all that when you’re not checking the channel every day, and it can be confusing to go through different recommendations by different members. The channel is a great way to share your thoughts, but there is no way of organizing those by name. To this end, I created the Appsmith Reading Club App, and here’s what I hoped it would do:

  • A way for non-members to also keep track of book recommendations
  • Be a one-stop-shop to see what Appsmith colleagues are reading without the clutter of the group chat

To build the app, here’s what I did:

Building a Rad UI

As a 'visual person,' and I feel most comfortable mapping out the elements and figuring out a flow. It helps me get a clear idea about what each component looks like and sets the scope.

I wanted one part of the app to be a list of names of the channel members, a button that could filter out their messages and display them in chronological order. Here are the widgets I used to build my UI. It took me under 10 minutes to put this together.

  • A table widget
  • A list widget
  • Text widgets
  • Image widgets

It's the next steps which are unfamiliar for a non-technical user like me: connecting a data source, writing code, and ensuring my app works! For this part, I enlisted my colleague, Vihar's help.

‍Here's a short tutorial!

‍Connecting Slack API‍

To pull information from a channel on Slack you need to work with the Slack API.

You have to then create an app and then generate OAuth tokens; to be able to do this, you need admin access to your organization’s Slack.

‍Here’s what our oauth configuration looks like:

oauth_config:
 scopes:
    user:
      - channels:history
      - channels:read
      - files:read
      - identify
      - users.profile:read
      - users:read
      - identity.basic

Next up, you have to link this configuration to your Appsmith application. This short tutorial uses the cloud version of Appsmith. However, you can always export and import Appsmith apps to different environments (cloud, self-hosted, local). The recommended way to use Appsmith is to use Docker; follow the documentation here for detailed instructions if you want to build locally.

In the next step, you will connect to the Slack API that will return all the users from the entire organisation. Since this is a secured API, we need to use the bearer token from the slack developer application to use it.

Follow the steps listed below:

  1. Click on the + icon next to the Data Sources.
  2. Select Authenticated API under the APIs section.
  3. Name the Query as completeList
  4. Use the following endpoint to fetch all the users from the slack organization: https://slack.com/api/users.list.
  5. Set the Authentication type to bearer token and copy the key here from the slack app. Hit RUN on the top right to execute the query.
image.png

Now in the response pane, you should be able to see all the users from the Slack organization. However, since our goal is only to fetch the users from a particular slack channel; in my case, this was #reading-club. For this, you have to write one more API that fetches details of a specific slack channel.

To do this, follow these steps:

  1. Click on the + icon next to the Data Sources.
  2. Select Authenticated API under the APIs section.
  3. Name the Query as filteredIds
  4. Use the following endpoint to fetch all the users from the slack organization: https://slack.com/api/conversations.members?channel=C01H8CPUVUK&limit=100.
  5. Set the Authentication type to bearer token and copy the key here from the slack app.
  6. Hit RUN on the top right to execute the query.

Here, as you can see, we’ve sent an additional parameter, which is channel-id. You can find this by clicking the details of the slack channel.

image.png

Now, to fetch all the messages from the slack channel, create a new query called getMessages. Follow the same steps, and replace the endpoint with the following:

https://slack.com/api/conversations.history?channel=C01H8CPUVUK&limit=1000

image.png

Here, you can limit the number of messages by sending an additional limit parameter. Now that we have everything, you can start building the UI for the app.

First step is to show all the members of the slack channel using a Table widget; when clicked, it will show all the book suggestions and other messages on a different List widget.

Follow these steps:

  1. Click on the + icon next to the widgets, find the Table widget, and drag and drop it onto the canvas.
  2. Open the table’s property pane by clicking on the cog icon on the table.
  3. Now, under the Table Data property, paste the following JS code snippet:
{{ 
function() {
    let all = completeList.data
    let filtered = filteredIds.data
    const result = all.members.filter(({
        id
    }) => filtered.members.includes(id));
    return result
}()
}}

In this snippet, we first fetched profiles of all the members in the slack organization and filtered them by user_ids with the selected slack channel. You can use a map function to return all the details of the users.

Next, we configure columns in the table by clicking on the cog icon for each column. For example, to render images from the API, we’ll need to access the profile key. Hence, we set the column type to image and set the column computed value to the following:

{{profile.image_original }}
image.png
image.png

With all the connections in place, the application will be fully functional. To take a look at my app, click here

‍It took me approximately 30-40 minutes to make this! My next steps would be to refine this app and add a few more elements, for example, displaying the date and time the messages were sent, images, and replies, filtering out system-generated messages, etc. While my experiments with Appsmith and this world of low code tools may have started with my soft spot for books, I quickly thought of other use-cases that can be implemented via the same app, such as automating other critical conversations/task-management on Slack channels or any other messaging applications. These would make my day-to-day job much easier! :)

It’s a pity that the world of internal apps is not given due attention simply because it’s not always customer-facing. Shifting our perspective to consider all users as customers can be a significant first step in building great internal apps. And low code is the future — internal applications can be tailor-made in a fraction of the time and cost while helping businesses focus on what matters most to their growth. ‍

I love hearing from our users and contributors. If you’re interested in building something on Appsmith or are currently building something, I'd love to pick your brain, please email me: vishnupriya@appsmith.com