Syntax - Backend services: Difference between revisions

From Izara Wiki
Jump to navigation Jump to search
Line 115: Line 115:


* all code should add the <syntaxhighlight lang="JavaScript" inline>'use strict';</syntaxhighlight> expression at the top of code (under license but before requires)
* all code should add the <syntaxhighlight lang="JavaScript" inline>'use strict';</syntaxhighlight> expression at the top of code (under license but before requires)
=== Iterating arrays and objects ===
* Standard methods to iterate arrays and objects:
==== Array, values only ====
* use <syntaxhighlight lang="JavaScript" inline>for (const value of array) {</syntaxhighlight>
* use ''const'' so inside the loop cannot change the value
* use <syntaxhighlight lang="JavaScript" inline>Array.isArray(array)</syntaxhighlight> to check if a variable is an array
* use ''map'' method when applicable, map returns an array of promises so works well with async-await (use await Promise.all if needed)
* avoid array.forEach: async-await code does not work as expected: [[https://gist.github.com/joeytwiddle/37d2085425c049629b80956d3c618971]]
* avoid array.forEach: cannot break/continue
==== Object, values only ====
* use <syntaxhighlight lang="JavaScript" inline>for .. in ..</syntaxhighlight> (will iterate inherited keys)
* or use <syntaxhighlight lang="JavaScript" inline>for (const value of Object.values(obj)) { }</syntaxhighlight> (only iterates this objects keys)
* for .. in iterates ''enumerable'' properties of an object.
==== Array, keys and values ====
* use <syntaxhighlight lang="JavaScript" inline>for(let key = 0; key < array.length; key++){ .. array[key] .. }</syntaxhighlight>
==== Objects, keys and values ====
* use <syntaxhighlight lang="JavaScript" inline>for (const [key, value] of Object.entries(obj)) { }</syntaxhighlight>
* for map use (?maybe not async) <syntaxhighlight lang="JavaScript" inline>const array = Object.entries(object).map(([key, value]) => { .. });</syntaxhighlight>
==== async: in serial ====
<syntaxhighlight lang="JavaScript">
for (const value of object) {
  await asyncFunction(value);
}
</syntaxhighlight>
==== async: in parallel ====
<syntaxhighlight lang="JavaScript">
let promises = array.map(async (value) => {
  await asyncFunction(value);
});
await Promise.all(promises);
</syntaxhighlight>


== Documenting code ==
== Documenting code ==

Revision as of 12:03, 11 January 2021

Overview

Syntax for services and code used in backend services deployed to AWS

Node

Code formatting

Indentation

  • 2 spaces
  • no tabs

New lines

  • \n (unix style)

White space

  • none at end of line
  • do not indent empty lines

Semi-colons

  • always add at end of statements

Quoting strings

  • single quotes
  • except in JSON or if string has single quote, can use double quotes then

Opening braces

  • place on same line as statement
  • correct:
if (true) {
  • wrong:
if(true)
{

Closing braces

  • else on same line as closing brace
  • correct:
} else {

Declaring var

  • one var declaration per line
  • wrong:
var keys = [foo, bar],
values = [23, 42],

Line length

  • less than 80 characters

Declaring variables

  • always declare constants using “const”, so cannot accidentally change
  • variables usually declare using “let” which scopes to block where possible, “var” is function scoped

Functions

  • In most cases use named functions


Naming Conventions

  • name should clearly represent the object

Variables, properties, function names

  • lowerCamelCase
  • if array add “s” on the end
  • no underscore/dashes, only A-Z/a-z
  • library functions we will often group into modules resembling entities in our design and the module will be named accordingly, when requiring these modules name the variables libXxxxx so that we do not clash with instances of those entities

Class and module names

  • UpperCamelCase

Constants

  • all UPPERCASE

Common abbreviations

  • Hdr = Handler
  • Msg = Message
  • Rcv = Receive
  • Snd = Send

Misc

requires at top

  • add all require’s at the top of the file

Boolean/null/undefined

  • always set to true or false, not 0/null/undefined
  • if we set something to empty use “null”
  • undefined: only when a new variable has not been set yet

'use strict';

  • all code should add the 'use strict'; expression at the top of code (under license but before requires)

Iterating arrays and objects

  • Standard methods to iterate arrays and objects:

Array, values only

  • use for (const value of array) {
  • use const so inside the loop cannot change the value
  • use Array.isArray(array) to check if a variable is an array
  • use map method when applicable, map returns an array of promises so works well with async-await (use await Promise.all if needed)
  • avoid array.forEach: async-await code does not work as expected: [[1]]
  • avoid array.forEach: cannot break/continue

Object, values only

  • use for .. in .. (will iterate inherited keys)
  • or use for (const value of Object.values(obj)) { } (only iterates this objects keys)
  • for .. in iterates enumerable properties of an object.

Array, keys and values

  • use for(let key = 0; key < array.length; key++){ .. array[key] .. }

Objects, keys and values

  • use for (const [key, value] of Object.entries(obj)) { }
  • for map use (?maybe not async) const array = Object.entries(object).map(([key, value]) => { .. });

async: in serial

for (const value of object) {
  await asyncFunction(value);
}

async: in parallel

let promises = array.map(async (value) => {
  await asyncFunction(value);
});
await Promise.all(promises);

Documenting code

Logging from code

  • use izara middleware logs
  • levels from least shown to most shown:
    • debug: the most detailed level, used when debugging an error
    • info: undesired situation, but is possible under normal conditions (eg request validation fail)
    • warning: unexpected situation, does not cause logic to fail (eg undefined instead of null)
    • error: critical situation that should not happen and causes logic to fail
  • ? confirm or fix ? log methods cannot take pure objects, must wrap in a new object, eg:
log.error(anObject);

will not work, should be:

log.error({anObject: anObject});

Jest

  • use “test” instead of “it”
  • try to make the test name a sentence for readability, eg:
test(xxx equals yyy)

Errors

  • When throwing an error, always create an Error object (don’t throw a string)


Database Syntax

Database tables

  • UpperCamelCase table names
  • name in plural (add “s” on the end) for main table, eg Products, child tables would remove the "s", eg ProductAttributes
  • no underscore/dashes, only A-Z/a-z

Database fields

  • lowerCamelCase
  • if array add “s” on the end
  • only A-Z/a-z, no dashes
  • avoid underscores except when the field is a composite of multiple fields or variables, then use underscore to separate them

Project File System Syntax

Node modules (files)

  • standard modules the perform operations prepend: Create / Update / Delete / List / Get
  • object name use singular (no “s”), for directories and module names

Directories

  • lowercase for standard dirs (src, app, __test__/unit/src)
  • UpperCamelCase for Service specific dirs

Filenames

  • UpperCamelCase for Service specific dirs
  • industry standard for standard/system dirs

Lambda

Function Errors when Direct Sync Invoke

  • If want to return an error to calling function, throw the error from the Lambda
  • Our standard is to check for that error in middleware eg handleInvokeSync function:

/mnt/WebsiteData/httpdocs/00_shop/IzaraCoreServices/izara-middleware/src/middleware_service_requests/lambda.js