Using the Rest extension - JavaScript

Procedure

  1. Create a new service in the Editor using rest as the value of the provision attribute.
  2. Reference the newly-created service by one or more operations.
      <service name="REST" provision="rest"/>  
      <mix name="Mix">
        ...
        <request name="FirstDivisor" service="REST" fields="n">
          <reply name="Ok" fields="div"/>
        </request>
        <request name="Test" service="REST" fields="div n">
          <reply name="No" fields="NO"/>
          <reply name="Iterate" fields="ITERATE"/>
        </request>
        <consume name="Iterate" service="REST" fields="ITERATE div n">
          <reply name="Next" fields="div n"/>
          <reply name="Stop" fields="YES"/>
        </consume>
      </mix>
  3. Start a new JavaScript module with importing the JavaScript class definition of a SPARKL service.
    // PrimesImpl.js
    
    importScripts("http://localhost:8000/rest/sparkl.Service.js")
  4. Define the JavaScript implementation of the operations on the service. You can either:
    • Create a new instance of the JavaScript SPARKL service and add the operations' implementation later.
    • Define the operations' implementation and add it at service creation time.

What to do next

You can also use the Rest extension as a client to trigger notify and solicit operations.

Creating a service instance first

Procedure

  1. Create an instance of the JavaScript SPARKL service.
    // PrimesImpl.js
    
    importScripts("http://localhost:8000/rest/sparkl.Service.js")
    
    /*
    An instance of sparkl.Service takes two or three arguments, where the third
    argument - the implementation of the operations - is optional. It is an empty
    dictionary if not given.
    sparkl.Service(ws_url, href) is the same as sparkl.Service(ws_url, href, {})
    */
    const service = new sparkl.Service(
      "ws://localhost:8000", "Scratch/Primes/REST");
    An instance of sparkl.Service takes the following arguments:
    • The base URL of the websocket connection
    • The Path to the rest service in the Navigation Tree panel
    • OPTIONAL - The implementation of the operations. An empty dictionary by default.
  2. Write the implementation of the operations and add them to the new service instance.
    // PrimesImpl.js
    
    importScripts("http://localhost:8000/rest/sparkl.Service.js")
    
    /*
    An instance of sparkl.Service takes two or three arguments, where the third
    argument - the implementation of the operations - is optional. It is an empty
    dictionary if not given.
    sparkl.Service(ws_url, href) is the same as sparkl.Service(ws_url, href, {})
    */
    const service = new sparkl.Service(
      "ws://localhost:8000", "Scratch/Primes/REST");
    
    // Implementation of Iterate operation.
    const iterateImpl = (request, callback) => {
        
        // Collect input fields from the request.
        var n =
          request.data.n;
        var div =
          request.data.div == 2 ? 3 : request.data.div + 2;
        
        // Send either the Stop reply.
        if (div > Math.sqrt(n)) {
          callback({
            reply: "Stop"});
        }
        
        // Or the Next reply.
        else {
          callback({
            reply: "Next",
            data: {
              n:    n,
              div:  div}});
        }
    };
    
    /* 
    Add implementation of the Iterate operation.
      - The key is the path to the operation (relative to the Rest service).
      - The value is the logic behind the operation - a lambda function. 
    */
    service.impl["Mix/Iterate"] = iterateImpl

Defining the operations' implementation first

Procedure

  1. Define the implementation of the operations.
    // PrimesImpl.js
    
    importScripts("http://localhost:8000/rest/sparkl.Service.js")
    
    // Implementation of the FirstDivisor operation.
    const FirstDivisor = (request, callback) => {
          
        // Send the Ok reply with div, assigning div the value 2.
        const reply = {
            reply: "Ok",
            data: {
              div: 2}
          };
    
          callback(reply);
        },
    ...
  2. Create a dictionary, using the path to the operations as keys and the operation implementations as values.
    Note: The paths are relative to the Rest service.
    // PrimesImpl.js
    
    importScripts("http://localhost:8000/rest/sparkl.Service.js")
    
    // Implementation of the FirstDivisor operation.
    const FirstDivisor = (request, callback) => {
          
        // Send the Ok reply with div, assigning div the value 2.
          const reply = {
            reply: "Ok",
            data: {
              div: 2}
          };
    
          callback(reply);
        },
    ...
    
    /* 
    Add the implementations to the impl constant - a dictionary.
    The paths are relative to the Rest service - Scratch/Primes/REST
    */
    const impl = {
        "Mix/FirstDivisor" : FirstDivisor, 
        ...
    }
  3. Create an instance of the SPARKL JavaScript service using the implementation map.
    // PrimesImpl.js
    
    importScripts("http://localhost:8000/rest/sparkl.Service.js")
    
    // Implementation of the FirstDivisor operation.
    const FirstDivisor = (request, callback) => {
          
        // Send the Ok reply with div, assigning div the value 2.
          const reply = {
            reply: "Ok",
            data: {
              div: 2}
          };
    
          callback(reply);
    };
    ...
    
    /* 
    Add the implementations to the impl constant - a dictionary.
    The paths are relative to the Rest service - Scratch/Primes/REST
    */
    const impl = {
        "Mix/FirstDivisor" : FirstDivisor, 
        ...
    }
    
    // Create the service instance using the operations' implementation.
    const service = new sparkl.Service(
      "ws://localhost:8000", "Scratch/Primes/REST", impl);
    An instance of sparkl.Service takes the following arguments:
    • The base URL of the websocket connection
    • The Path to the rest service in the Navigation Tree panel
    • OPTIONAL - The implementation of the operations. An empty dictionary by default.

Using client-side operations

You can use a rest service to trigger solicit and notify operations from within a JavaScript module.

Before you begin

Make sure you have already created the JavaScript SPARKL service using the sparkl.Service constructor.

Procedure

  1. Create a notify or solicit operation in the Editor.
  2. Reference the rest-provisioned service in the operation's clients attribute.
  3. Depending on the type of the operation, use either:
    • The notify method.
      importScripts("http://localhost:8000/rest/sparkl.Service.js")
      
      const restService = new sparkl.Service(
        "ws://localhost:8000", "Scratch/Discounts/REST");
      
      // Invoke Start notify operation. It outputs only a FLAG field.
      restService.notify({
          notify: "Mix/Impl/Alerts/Start"
      });
      The notify method takes a dictionary as its argument. It specifies:
      • The path to the notify in the user tree. The path is resolved relative to the rest service.
      • The optional data dictionary, which declares the fields the notify outputs and the values of the fields. Not mandatory if the operation only outputs FLAG fields.
    • The solicit method.
      importScripts("http://localhost:8000/rest/sparkl.Service.js")
      
      const tinyService = new sparkl.Service(
        "ws://localhost:8000", "Scratch/TinyTable/Mix/REST");
      
      /** Callback function used by the Delete solicit.
      * If the delete operation fails, prints the value of the
      * error response field. */
      var checkDelete = result => {
          if (result.response == "Error") {
            console.log(result.data.error);
          }
        };
      
      // Invoke Delete solicit with the ID field, with a value of 3.
      tinyService.solicit({
          solicit: "API/Delete",
          data: {
            id: 3
          }}, checkDelete);
      };
      The solicit method takes a dictionary as its argument, and an optional callback function. The dictionary specifies:
      • The path to the solicit in the user tree. The path is resolved relative to the rest service.
      • The optional data dictionary, which declares the fields the solicit outputs and the values of the fields. Not mandatory if the operation only outputs FLAG fields.
      The callback function takes the response as its sole argument. Use it to verify the response sent by SPARKL.