Open In App

HTTP REST API Calls in ElectronJS

Improve
Improve
Like Article
Like
Save
Share
Report

ElectronJS is an Open Source Framework used for building Cross-Platform native desktop applications using web technologies such as HTML, CSS, and JavaScript which are capable of running on Windows, macOS, and Linux operating systems. It combines the Chromium engine and NodeJS into a Single Runtime.

We already know about the importance of HTTP REST API’s in any system. They are used everywhere globally and there are dedicated resources available on the internet that cover everything regarding HTTP REST API’s, standards, and protocols in detail. Some of the more famous resources for HTTP REST are mentioned here and here. NodeJS provides extensive support for making HTTP REST API calls via built-in modules and external packages. NodeJS provides us with built-in HTTP and HTTPS modules and some of the most famous npm packages used in NodeJS are axios, request and node-fetch. Since Electron is essentially a Node application, all of the above-mentioned packages are supported and can be used in Electron as well. For a short tutorial on how to use axios package in Electron for making REST API calls, Refer the article: Geo Information in ElectronJS. In addition to the above, Electron also provides us with a built-in net Module for this very purpose. The net module is used for issuing HTTP/HTTPS REST requests using Chromium’s native networking library. This tutorial will demonstrate how to make HTTP REST API calls in Electron using the net module and the advantages and features of the net module. 

We assume that you are familiar with the prerequisites as covered in the above-mentioned link. For Electron to work, node and npm need to be pre-installed in the system.

The net Module is a client-side API in Electron for issuing HTTP/HTTPS requests. As mentioned above, It is similar to the HTTP and HTTPS modules of NodeJS but it uses Chromium’s native networking library instead of the NodeJS implementation and therefore offers better support for web proxies. Some other advantages of the net Module are: 

  • Automatic management of system proxy configuration, support of the WPAD(Web Proxy Auto-Discovery) protocol and proxy pac configuration files.
  • Automatic tunneling of HTTPS requests.
  • Support for authenticating proxies using basic, digest, NTLM, Kerberos or negotiate authentication schemes.
  • Support for traffic monitoring proxies: Fiddler-like proxies used for access control and monitoring.

Project Structure: 

Project Structure

Example: Follow the Steps given in Dynamic Styling in ElectronJS to set up the basic Electron Application. Copy the Boilerplate code for the main.js file and the index.html file as provided in the article. Also, perform the necessary changes mentioned for the package.json file to launch the Electron Application. We will continue building our application using the same code base. The basic steps required to set up the Electron application remain the same.

package.json: 

{
    "name": "electron-net",
        "version": "1.0.0",
            "description": "Making HTTP REST API Calls - net Module in Electron ",
                "main": "main.js",
                    "scripts": {
        "start": "electron ."
    },
    "keywords": [
        "electron"
    ],
        "author": "Radhesh Khanna",
            "license": "ISC",
                "dependencies": {
        "electron": "^8.3.0"
    }
}

Output: 

HTTP REST API Calls in Electron The net module in Electron is part of the Main Process. To import and use the net module in the Renderer Process, we will be using Electron remote module. In this tutorial, we have used httpbin.org which is a simple and free 3rd Party HTTP REST Request & Response Service. It provides sample HTTP REST API’s which are publicly available and do not require any authentication and authorization. It also provides many other features such as authentication tests, redirects, cookies, dynamic and randomized data, etc, through sample REST API’s. We will be making HTTP GET and HTTP POST Requests to this service for demonstration purposes using the net module. All the components used in the net Module including design and implementation such as Instance methods, Instance events and Instance properties are similar to NodeJS implementation. This net module can only be used after the ready event of the app module is emitted. This module is supported on all OS platforms and environments.

  • index.html: Add the following snippet in that file.

html




<h3>Making HTTP REST API Calls
    using net Module in Electron
</h3>
<button id="get">
    Make Sample GET Request
</button>
<br><br>
<button id="post">
    Make Sample POST Request
</button>
<!-- Adding Individual Renderer
    Process JS File -->
<script src="index.js"></script>


  • index.js: The Make Sample GET Request and Make Sample POST Request buttons do not have any functionality associated with them yet.

javascript




const electron = require('electron');
// Importing the net Module from electron remote
const net = electron.remote.net;
 
let get = document.getElementById('get');
get.addEventListener('click', () => {
    const request = net.request({
        method: 'GET',
        protocol: 'http:',
        hostname: 'httpbin.org',
        path: '/get',
        redirect: 'follow'
    });
    request.on('response', (response) => {
        console.log(`STATUS: ${response.statusCode}`);
        console.log(`HEADERS: ${JSON.stringify(response.headers)}`);
 
        response.on('data', (chunk) => {
            console.log(`BODY: ${chunk}`)
        });
    });
    request.on('finish', () => {
        console.log('Request is Finished')
    });
    request.on('abort', () => {
        console.log('Request is Aborted')
    });
    request.on('error', (error) => {
        console.log(`ERROR: ${JSON.stringify(error)}`)
    });
    request.on('close', (error) => {
        console.log('Last Transaction has occurred')
    });
    request.setHeader('Content-Type', 'application/json');
    request.end();
});
 
let post = document.getElementById('post');
post.addEventListener('click', () => {
    let body = JSON.stringify({ key: 1 });
    const request = net.request({
        method: 'POST',
        protocol: 'http:',
        hostname: 'httpbin.org',
        path: '/post',
        redirect: 'follow'
    });
    request.on('response', (response) => {
        console.log(`STATUS: ${response.statusCode}`);
        console.log(`HEADERS: ${JSON.stringify(response.headers)}`);
 
        response.on('data', (chunk) => {
            console.log(`BODY: ${chunk}`)
        });
    });
    request.on('finish', () => {
        console.log('Request is Finished')
    });
    request.on('abort', () => {
        console.log('Request is Aborted')
    });
    request.on('error', (error) => {
        console.log(`ERROR: ${JSON.stringify(error)}`)
    });
    request.on('close', (error) => {
        console.log('Last Transaction has occurred')
    });
    request.setHeader('Content-Type', 'application/json');
    request.write(body, 'utf-8');
    request.end();
});


Explanation: The net module supports only one Instance method. This net.request(options) Instance method uses the ClientRequest Instance. Every call to this Instance method is created and returns a new ClientRequest Instance. This instance method is used to issue both secure and insecure HTTP requests according to the specified protocol scheme in the options object. For more detailed information on the net.request() method. It takes in the following parameters. 

  • Options: The Object/String This Parameter can take in an Object or just a simple String value. This represents the ClientRequest Constructor options and is directly forwarded to the ClientRequest Instance. If this parameter is a String, it is interpreted as the request URL. If it is an object, it is expected to fully specify an HTTP request as supported by the ClientRequest constructor. 

All Instance methods, events, and properties further used in the above code are part of the ClientRequest Instance. The ClientRequest Instance makes the actual HTTP/HTTPS requests and it implements the Writable Stream interface and is therefore an EventEmitter. A detailed Explanation of the ClientRequest constructor options is given below. It supports the following parameters: 

  • Method: This parameter specifies the HTTP request method. It defaults to the HTTP GET method.
  • URL: This parameter specifies the HTTP request URL. This parameter must be provided in the absolute form with the protocol specified as http: or https:. In case the protocol is not provided, no default value is set and hence the HTTP request will fail. For a simple HTTP GET request, specifying the method and the url parameters are sufficient to make the call. The URL parameter can further be dissected into other parameters as well.
  • Session: This parameter specifies the Electron Session Instance with which the request is associated.
  • Partition: String (Optional) This parameter specifies the name of the partition as derived from the Session Instance with which the request is associated. The default value is an empty string. If the session parameter and the partition parameter are defined together, the session parameter takes precedence. Thus if a session Instance is explicitly specified and passed, the partition parameter is ignored.
  • useSessionCookies: This parameter specifies whether to send cookies with this request as derived from the Session Instance. This will make the net modules request’s cookie behavior match a NodeJS fetch request. The default value is false.
  • Protocol: String (Optional) This parameter specifies the protocol scheme of the HTTP request. Currently supported values are http: or https:. The default value is http:. This parameter strictly follows the NodeJS model as described in the URL Module.
  • Host: This parameter specifies the server host i.e. the base URL provided as a concatenation of the hostname parameter and the port number parameter in the format of hostname:port as followed in the URL standards. This parameter strictly follows the NodeJS model as described in the URL Module.
  • Hostname: String (Optional) This parameter specifies the server host name. It can be a DNS (Domain Name Service) server name or an IP Address. This parameter strictly follows the NodeJS model as described in the URL Module.
  • Port: Integer (Optional) This parameter specifies the server’s listening port number. This parameter strictly follows the NodeJS model as described in the URL Module.
  • Path: String (Optional) This parameter specifies the path part of the request URL i.e. the part that follows after the base URL hostname/host/port parameters. This parameter can contain the Query String parameters or the path parameters as well that are required to be passed to the REST API. The Query String parameters are defined after the? With a key-value pair in the URL. This parameter strictly follows the NodeJS model as described in the URL Module.
  • redirect: String (Optional) This parameter defines the redirect mode for the HTTP request. It can hold any of the following values:
    • follow Follows default behaviour of the HTTP request.
    • error Aborts any or all redirections in the HTTP request.
    • manual Cancels the Redirection unless the request.followRedirect() Instance method is invoked synchronously while the redirect Instance event is emitted.

The ClientRequest Instance supports the following Instance Events. 

  • response: Event This Instance event is emitted when the HTTP request has been processed and returns a response from the REST API. This Instance event is emitted on the net module object (In this case, request object). It returns a single response: Object which represents the Incoming HTTP response packet which includes the HTTP Status, HTTP Headers, HTTP body, etc.
  • finish: Event This Instance event is emitted just after the last chunk of the HTTP request’s data has been received and written into the request object.
  • abort: Event This Instance event is emitted when the HTTP request is aborted. This event will not be emitted if the request is already closed i.e. the close Instance event has been fired.
  • error: Event This Instance event is emitted when the net module fails to issue an HTTP network request which can happen due to a variety of reasons such as Bad Gateway, No network connection, etc. Typically when the request object emits an error Instance event, a close Instance event is also emitted just after and no response object will be provided. This event returns an error object which contains some information about the failure of the HTTP request such as the HTTP status code, etc.
  • close: Event This Instance event is emitted as the last event in the HTTP request-response transaction after the Handshake is complete. This event indicates that no further events will be emitted on either the request or response objects and marks the transaction as complete. 

Additionally, the ClientRequest Instance supports a single Instance Property. 

  • request.chunkedEncoding This Instance property takes in a Boolean value. This property specifies whether the HTTP request will use HTTP chunked transfer encoding or not. This property can only be set before the first write operation i.e. before the request.write() Instance method as the HTTP headers are not yet put on the wire. Trying to set the chunkedEncoding property after the first write will throw an error. The default value is false. Using chunkedEncoding Instance property as true is strongly recommended if you need to send a large request body as data will be streamed in small chunks instead of being internally buffered inside Electron process memory. 

Based on the ClientRequest constructor options and the Instance events and properties we have covered up till now, we notice that some critical parameters for HTTP requests are missing such as the headers and the body in case of the HTTP POST request. This is because these parameters were removed from the constructor options object from the previous versions of Electron and added as separate Instance methods in the newer versions. The ClientRequest Instance supports the following Instance Method. 

  • request.setHeader(name, value) This Instance method is used to add an extra HTTP header or overwrite an existing header apart from default HTTP headers. The header name will be used as it is without lowercasing it. It can be called only before first write i.e. before the request.write() Instance method is called. Calling this method after the first write will throw an error. If the passed value is not a String, its toString() method will be called to obtain the final value before setting the headers in the HTTP request packet.
  • request.getHeader(name) This Instance method is used to return the value of the header as passed in the name: String parameter. The returned value is a string containing the value.
  • request.removeHeader(name) This Instance method is used to remove the header as passed in the name: String parameter. It can be called only before first write i.e. before the request.write() Instance method is called. Calling this method after the first write will throw an error. This method does not return any values.
  • request.write(chunk, encoding, callback) This Instance method adds a chunk of data to the request body. This Instance method is where we set the Body of the HTTP POST Request. The first write operation may cause the request headers to be issued on the wire. After the first write operation, it is not allowed to add or remove a custom header. It takes in the following parameters:
    • chunk: String/Buffer A chunk of the request body’s data. If it is a String value, it is converted internally into a Buffer using the specified encoding in the encoding parameter.
    • encoding: String (Optional) This parameter as mentioned above, is used to convert the chunk parameter String value into a Buffer object. The default value used for encoding is utf-8 which is the default encoding used when transferring HTTP requests over the wire.
    • callback: Function (Optional) This callback function is essentially a dummy function introduced for the purpose of keeping similarity with the NodeJS API. It is called asynchronously after chunk content has been delivered to the Chromium networking layer.
  • request.abort() This Instance method if called, cancels an ongoing HTTP Transaction. If the close Instance event is already emitted, this Instance method will have no effect. Else abort and close Instance events are emitted. Additionally, if there is an ongoing response object, it will also emit the abort Instance event.
  • request.followRedirect() This Instance method continues and forces through any pending redirection of the HTTP request. This Instance method can only be called when a redirect Instance event is emitted. 

At this point, upon launching the Electron application, we should be able to make Successful HTTP REST API calls to the httpbin.org HTTP Service, GET and POST Sample APIs and check the responses that we are getting from these APIs. 

Output: 



Last Updated : 06 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads