Node.js best practice to populate JSON request

Intro

I'm currently using the UPS Rate API to create a shipping plugin for a client to get an estimate on shipping charges for customers during checkout (among other things).

I've briefly used Nodejs in the past, however this would be my first time using it in a production environment, and I want to ensure I'm using best practices for this application.

Code

Below is the request I must send to UPS' API endpoint to get a shipping estimate:

{
   "UPSSecurity":{
      "UsernameToken":{
         "Username":"Your User Id",
         "Password":"Your Password"
      },
      "ServiceAccessToken":{
         "AccessLicenseNumber":"Your Access License"
      }
   },
   "RateRequest":{
      "Request":{
         "RequestOption":"Rate",
         "TransactionReference":{
            "CustomerContext":"Your Customer Context"
         }
      },
      "Shipment":{
         "Shipper":{
            "Name":"Shipper Name",
            "ShipperNumber":"Shipper Number",
            "Address":{
               "AddressLine":[
                  "Address Line ",
                  "Address Line ",
                  "Address Line "
               ],
               "City":"City",
               "StateProvinceCode":"State Province Code",
               "PostalCode":"Postal Code",
               "CountryCode":"US"
            }
         },
         "ShipTo":{
            "Name":"Ship To Name",
            "Address":{
               "AddressLine":[
                  "Address Line ",
                  "Address Line ",
                  "Address Line "
               ],
               "City":"City",
               "StateProvinceCode":"State Province Code",
               "PostalCode":"Postal Code",
               "CountryCode":"US"
            }
         },
         "ShipFrom":{
            "Name":"Ship From Name",
            "Address":{
               "AddressLine":[
                  "Address Line ",
                  "Address Line ",
                  "Address Line "
               ],
               "City":"City",
               "StateProvinceCode":"State Province Code",
               "PostalCode":"Postal Code",
               "CountryCode":"US"
            }
         },
         "Service":{
            "Code":"03",
            "Description":"Service Code Description"
         },
         "Package":{
            "PackagingType":{
               "Code":"02",
               "Description":"Rate"
            },
            "Dimensions":{
               "UnitOfMeasurement":{
                  "Code":"IN",
                  "Description":"inches"
               },
               "Length":"5",
               "Width":"4",
               "Height":"3"
            },
            "PackageWeight":{
               "UnitOfMeasurement":{
                  "Code":"Lbs",
                  "Description":"pounds"
               },
               "Weight":"1"
            }
         },
         "ShipmentRatingOptions":{
            "NegotiatedRatesIndicator":""
         }
      }
   }
}

Seeing the amount of fields to fill out, whats the best way to approach this, while adhering to basic software engineering principles of low coupling and high cohesion?

Should I do something similar to the code example below, but for each field section?

const shipToAddr1 = "A street with number"
const shipToAddr2 = "Line 2 with number"
const shipToAddr3 = "The third line"
const shipToCity = "Boston"
const shipToStateProvinceCode = "12"
const shipToPostalCode = "01970"
const shipToCountryCode = "US"
const shipToName = "Bob Wallace"

const packageLength = "10"
const packageWidth = "5"
const packageHeight = "18"
const PackageWeight = "12"

//See above code snippet
var jsonRequest = {...}

function writeShipToContents(json, shipToName, shipToAddr1, shipToAddr2, 
    shipToAddr3){

    json.RateRequest.Shipment.ShipTo.Name = shipToName
    json.RateRequest.Shipment.ShipTo.Address.AddressLine = [
        shipToAddr1,
        shipToAddr2,
        shipToAddr3
        ]

}

function writeShipFromContents(json){
   ...
}

function writePackageDetails(json){
   ...
}


function writeShipmentRequest(json){

   writeShipToContents(json)
   writeShipFromContents(json)
   writePackageDetails(json)

   ...

   return json

}

writeShipmentRequest(jsonRequest)

My instinct is that many things are wrong with the above code, for instance having each function change the referenced object instead of returning a new object with the populated contents; having the functions use global variables to populate the information; and all in all, this seems like a lot of code for a simple task.

The application will take a POST request with the information as const in the example, then return the results of the shipping estimate.

Should I be creating a dictionary of each field, pass the json and the dictionary contents, and have the function lookup the dictionary items, populate the json, and return the results?

2 answers

  • answered 2018-01-11 19:44 Matthew Lagerwey

    The first thing to use best practice is to use object literals instead of polluting global namespace const anyObject = { // your object } the second thing is to use functional programming techniques function( anyObject, argsToDo) { // do what every you want to anyObject with other functions // anyObject could contain all the properties you need to write // () => setWhatever(anyObject) // or return new anyObjectWithArgsToDo(); } you can use the approach to write the fields dynamically for the JSON object that you need to submit example pseudocode: function writeFields( anyObject, fieldsObject ) { let i = 0; foreach( anyObject as value ) { value = fieldsObject[I]; i++; }

    you can combined objects to hold other objects JSON stands for JavaScript Object Notation so you can pass them as an argument to functions, perform operations on them with functions, create new Objects with objects as arguments et. cetera. Here is a link to the Wiki on functional programming https://en.wikipedia.org/wiki/Functional_programming. To use modern programming techniques would be to use a layer of abstraction and encapsulation among other things, it appears as though you are writing to the implementation instead of writing reusable code that performs a task. The best way to write the code is so that it would work with any object, that involves the use of functional programming techniques where the function does not care about the state of it's arguments. Example function writeSomeObject ( object, property, value) { object[${property}] = ${value}; // use back ticks // that allow dynamic use of arguments } I hope that helps

  • answered 2018-01-11 19:44 Julien Ambos

    Don't overthink this with unnecessary programming paradigms. According to your comment this is a simple creation of an object whose structure never changes. Treat it as such.

    If your task is to create a Javascript Object from values and send it in a POST request, simply create a Javascript Object with the short notation:

    const upsPostBody = {
        property: value
    }
    

    Do this for the whole object, e.g. (excerpt):

    const username = 'Your User Id';
    const password = 'Your Password';
    const accessLicenseNumber: 'Your Access License';
    
    const upsPostBody = {
       UPSSecurity:{
          UsernameToken: {
             Username: username,
             Password: password
          },
          ServiceAccessToken: {
             AccessLicenseNumber: accessLicenseNumber
          }
       }
       // Continue for all other keys and values
    }
    

    After assigning the values to the object, pass the object as the body to your POST method.