Syntax - Backend services: Difference between revisions

From Izara Wiki
Jump to navigation Jump to search
 
(3 intermediate revisions by the same user not shown)
Line 92: Line 92:


* all UPPERCASE
* all UPPERCASE
* use underscores to separate words


=== Common abbreviations ===
=== Common abbreviations ===
Line 115: Line 116:


* 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 ==
Line 175: Line 221:
== Directories ==
== Directories ==


* lowercase for standard dirs (src, app, __test__/unit/src)
* lowercase for standard dirs (src, app, __test__/unit/src, src/libs)
* UpperCamelCase for Service specific dirs
* UpperCamelCase for Service specific dirs
* shared functions go into libs folder, each lib file us UpperCaseCamel and ends in ..Lib so clearly identified, when requiring the variable name matches the file name but lowerCaseCamel


== Filenames ==
== Filenames ==
Line 190: Line 237:
* Our standard is to check for that error in middleware eg handleInvokeSync function:
* 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
/mnt/WebsiteData/httpdocs/00_shop/IzaraCoreServices/izara-middleware/src/middleware_service_requests/lambda.js
= Neo4j graphs =
== Node Labels ==
* lowerCaseCamel
== Relationship Types ==
* lowerCaseCamel
* if we are building a relationship type that connects with a node label, eg "has_product", use an underscore between the relationship prefix and the node label
== Node and Relationship properties ==
* lowerCaseCamel

Latest revision as of 14:46, 8 November 2022

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
  • use underscores to separate words

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, src/libs)
  • UpperCamelCase for Service specific dirs
  • shared functions go into libs folder, each lib file us UpperCaseCamel and ends in ..Lib so clearly identified, when requiring the variable name matches the file name but lowerCaseCamel

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

Neo4j graphs

Node Labels

  • lowerCaseCamel

Relationship Types

  • lowerCaseCamel
  • if we are building a relationship type that connects with a node label, eg "has_product", use an underscore between the relationship prefix and the node label

Node and Relationship properties

  • lowerCaseCamel