├── .github └── workflows │ ├── npcheck.yml │ ├── style.yml │ └── website.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── assets │ └── cors-error.png ├── development │ ├── _category_.json │ ├── accessibility.md │ ├── building-good-containers.md │ ├── ci-cd.md │ ├── code-consistency.md │ ├── code-coverage.md │ ├── cross-origin.md │ ├── dependencies.md │ ├── dev-flows.md │ ├── kubernetes-dev-environment.md │ ├── mono-repository.md │ ├── npm-package-development.md │ ├── npm-proxy.md │ ├── npm-publishing.md │ ├── protecting-code.md │ ├── secure-development-process.md │ ├── serverless.md │ ├── testing.md │ └── typescript.md ├── functional-components │ ├── _category_.json │ ├── auth.md │ ├── consuming-services.md │ ├── data-caching.md │ ├── databases.md │ ├── graphql.md │ ├── internationalization.md │ ├── message-queuing.md │ ├── nodejs-versions-images.md │ ├── rest-api-development.md │ ├── scaling-multi-threading.md │ ├── static-assets.md │ ├── template-engines.md │ ├── transaction-handling.md │ └── webframework.md ├── intro.md └── operations │ ├── _category_.json │ ├── distributed-tracing.md │ ├── failurehandling.md │ ├── healthchecks.md │ ├── logging.md │ ├── metrics.md │ └── problem-determination.md ├── npcheck-review ├── npcheck-April7-2025.md ├── npcheck-apr15-2024.md ├── npcheck-april-15-2023.md ├── npcheck-dec6-2021.md ├── npcheck-jan4-2023.md ├── npcheck-jan9-2024.md ├── npcheck-january29-2025.md ├── npcheck-jul1-2024.md ├── npcheck-july21-2023.md ├── npcheck-july22-2021.md ├── npcheck-july7-2022.md ├── npcheck-march19-2022.md ├── npcheck-oct10-2023.md ├── npcheck-oct11-2024.md └── npcheck-oct20-2022.md ├── npcheck.json ├── package.json └── website ├── .gitignore ├── README.md ├── babel.config.js ├── docusaurus.config.js ├── package.json ├── sidebars.js ├── src └── pages │ └── index.js_disabled └── static ├── .nojekyll ├── favicon.ico └── img ├── docusaurus.png └── logo.svg /.github/workflows/npcheck.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run the due dilligence checks provided by `npcheck`: 2 | # - On demand. 3 | # - Regularly (once a week). 4 | # - When `npcheck.json` or this workflow file is changed. 5 | 6 | name: Due Dilligence 7 | 8 | on: 9 | workflow_dispatch: 10 | schedule: 11 | - cron: "0 0 * * 0" 12 | push: 13 | branches: [ main ] 14 | paths: 15 | - ".github/workflows/npcheck.yml" 16 | - "npcheck.json" 17 | pull_request: 18 | branches: [ main ] 19 | paths: 20 | - ".github/workflows/npcheck.yml" 21 | - "npcheck.json" 22 | jobs: 23 | build: 24 | runs-on: ubuntu-latest 25 | strategy: 26 | matrix: 27 | node-version: [ lts/* ] 28 | 29 | steps: 30 | - uses: actions/checkout@v3 31 | - name: Use Node.js ${{ matrix.node-version }} 32 | uses: actions/setup-node@v3 33 | with: 34 | node-version: ${{ matrix.node-version }} 35 | - run: npx npcheck@latest --version; npx npcheck@latest --github-token ${{ secrets.GITHUB_TOKEN }} 36 | -------------------------------------------------------------------------------- /.github/workflows/style.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: StyleCheck 5 | 6 | on: 7 | workflow_dispatch: 8 | schedule: 9 | - cron: "0 0 * * 0" 10 | push: 11 | branches: [ main ] 12 | paths: 13 | - "docs/**" 14 | pull_request: 15 | branches: [ main ] 16 | paths: 17 | - "docs/**" 18 | jobs: 19 | build: 20 | 21 | runs-on: ubuntu-latest 22 | 23 | strategy: 24 | matrix: 25 | node-version: [16.x] 26 | 27 | steps: 28 | - uses: actions/checkout@v3 29 | - name: Use Node.js ${{ matrix.node-version }} 30 | uses: actions/setup-node@v3 31 | with: 32 | node-version: ${{ matrix.node-version }} 33 | - run: npm install && npm run lint 34 | -------------------------------------------------------------------------------- /.github/workflows/website.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: WebsiteCI 5 | 6 | on: 7 | push: 8 | branches: [ main ] 9 | paths: 10 | - "website/**" 11 | - "docs/**" 12 | pull_request: 13 | branches: [ main ] 14 | paths: 15 | - "website/**" 16 | - "docs/**" 17 | jobs: 18 | build: 19 | 20 | runs-on: ubuntu-latest 21 | 22 | strategy: 23 | matrix: 24 | node-version: [16.x] 25 | 26 | steps: 27 | - uses: actions/checkout@v3 28 | - name: Use Node.js ${{ matrix.node-version }} 29 | uses: actions/setup-node@v3 30 | with: 31 | node-version: ${{ matrix.node-version }} 32 | - run: cd website && npm install && npm run copyDocs && npm run build 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | node_modules 3 | yarn.lock -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at info@nodeshift.dev. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are welcome through pull requests, however, the reference architecture 4 | is intended to reflect the opinion of Red Hat and IBM based on the key tenets 5 | outlined in the README.md. Therefore only PR's which are aligned with that 6 | opinion will be accepted. 7 | 8 | ## Checking formatting and style 9 | 10 | Before pushing changes contributors need to ensure that their markdown spec is valid 11 | by executing 12 | 13 | ``` 14 | npm install 15 | npm run lint 16 | ``` 17 | 18 | ## Adding new documents that appear on website 19 | 20 | Reference architecture uses docusaurus website that requires each file to supply additional metadata 21 | At minimum file needs to have following header (where position is the next position that we have in current category) 22 | ``` 23 | --- 24 | sidebar_position: 1 25 | --- 26 | ``` 27 | 28 | For more info please see: https://docusaurus.io/docs/create-doc 29 | 30 | 31 | ## Building and publishing website 32 | 33 | Website can be published by following commands 34 | 35 | ``` 36 | cd website 37 | yarn 38 | yarn copyDocs 39 | GIT_USER= USE_SSH=true yarn deploy 40 | ``` 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node.js Reference Architecture 2 | 3 | ## Overview 4 | 5 | The goal of the Node.js reference architecture is to present 6 | the `teams` 'opinion' on what components our customers 7 | and internal teams should use when building Node.js applications 8 | and guidance for how to be successful in production with those components. 9 | 10 | Traditionally there has been reluctance to recommend a subset 11 | of the packages the JavaScript ecosystem but our customers are increasingly 12 | looking to the `team` for an opinion of where to start. 13 | 14 | The components in this architecture are what we recommend to help internal 15 | and external customers get started based on our experience. Other components may be equally 16 | good, but these are the ones we know best and have the most experience with. 17 | 18 | - Where possible the opinion is based on what we've used internally and in our customer engagements. 19 | - The components specified will be our first priority for our contributions to open source projects in the JavaScript ecosystem. 20 | - Due to the above these are the components the `team` is best positioned when working with internal and external customers. 21 | However, we do not include formal support for these components in any of our support offerings unless specifically identified 22 | in those offerings. 23 | - The recommended components may change over time as technologies and approaches change. 24 | 25 | If you want to learn more about some of the discussions that went into the Node.js reference architecture you can check out the [Introduction to the Node.js reference architecture](https://developers.redhat.com/blog/2021/03/08/introduction-to-the-node-js-reference-architecture-part-1-overview) blog post series. 26 | 27 | ### The team 28 | 29 | The `team` consists of engineers from across groups within IBM and Red Hat who: 30 | 31 | - are actively engaged in the JavaScript/Node.js community 32 | - have large Javascript/Node.js deployments 33 | - provide consulting advice and/or development related to JavaScript/Node.js for customers 34 | - develop/deliver JavaScript or Node.js components 35 | 36 | ### Key tenets 37 | 38 | - Whenever possible components should have been validated at scale within the `team's` 39 | JavaScript/Node.js deployments or in engagements with our customers. 40 | - We need to consider licensing and other due diligence when selecting components. 41 | - We are going to start with a focus on the back-end, a similar effort for front-end 42 | components will make sense as a follow on. 43 | 44 | ## Components 45 | 46 | The reference architecture covers the following components (currently a work in progress 47 | with only a subset of sections having recommendations): 48 | 49 | #### Functional Components 50 | 51 | - [Web Framework](./docs/functional-components/webframework.md) 52 | - [Template Engines](./docs/functional-components/template-engines.md) 53 | - [Message Queuing](./docs/functional-components/message-queuing.md) 54 | - [Internationalization](./docs/functional-components/internationalization.md) 55 | - [GraphQL](./docs/functional-components/graphql.md) 56 | - [Databases](./docs/functional-components/databases.md) 57 | - [Authentication and Authorization](./docs/functional-components/auth.md) 58 | - [Data Caching](./docs/functional-components/data-caching.md) 59 | - [REST API Development](./docs/functional-components/rest-api-development.md) 60 | - [Load Balancing, Scaling and Multi-threading](./docs/functional-components/scaling-multi-threading.md) 61 | - [Consuming Services](./docs/functional-components/consuming-services.md) 62 | - [Node versions/images](./docs/functional-components/nodejs-versions-images.md) 63 | - [Transactions_handling](./docs/functional-components/transaction-handling.md) 64 | 65 | #### Development 66 | 67 | - [Typical Development Workflows](./docs/development/dev-flows.md) 68 | - [Kubernetes-based Development Environment](./docs/development/kubernetes-dev-environment.md) 69 | - [Choosing and vetting dependencies](./docs/development/dependencies.md) 70 | - [Building good containers](./docs/development/building-good-containers.md) 71 | - [Static Assets](./docs/functional-components/static-assets.md) 72 | - [Protecting Code](./docs/development/protecting-code.md) 73 | - Code Quality 74 | - [Code Consistency](./docs/development/code-consistency.md) 75 | - [Testing](./docs/development/testing.md) 76 | - [Code Coverage](./docs/development/code-coverage.md) 77 | - [TypeScript](./docs/development/typescript.md) 78 | - [Accessibility](./docs/development/accessibility.md) 79 | - [Cross Origin Communication](./docs/development/cross-origin.md) 80 | - [CI/CD](./docs/development/ci-cd.md) 81 | - Npm 82 | - [Npm Proxy / Internal Registries](./docs/development/npm-proxy.md) 83 | - [Npm Publishing](./docs/development/npm-publishing.md) 84 | - [Package Development](./docs/development/npm-package-development.md) 85 | - [Secure Development Process](./docs/development/secure-development-process.md) 86 | - [Serverless](./docs/development/serverless.md) 87 | 88 | #### Operations 89 | - Monitoring 90 | - [Logging](./docs/operations/logging.md) 91 | - [Metrics Collection](./docs/operations/metrics.md) 92 | - [Health Checks](./docs/operations/healthchecks.md) 93 | - [Distributed Tracing](./docs/operations/distributed-tracing.md) 94 | - [Problem Determination](./docs/operations/problem-determination.md) 95 | - [Failure Handling](./docs/operations/failurehandling.md) 96 | 97 | ## Module Diligence 98 | 99 | As a minimum, any modules recommended as part of this reference architecture should meet the following criteria: 100 | 101 | - The module is not deprecated. 102 | - The module has an appropriate license. 103 | - Generally leaning towards permissive licenses such as MIT - others should be reviewed on case by case basis. 104 | - The module runs on LTS versions of Node.js. 105 | - The module has appropriate testing. 106 | - The module is appropriately maintained: 107 | - Regular releases (where appropriate). 108 | - Critical bugs reports are acknowledged and addressed. 109 | - Reported security vulnerabilities are patched and released. 110 | 111 | ## Contributing 112 | 113 | To Contribute to this project, please see the [Contributing Guide](./CONTRIBUTING.md). 114 | 115 | ## Contributors 116 | 117 | - Anthony Whalley - Technology Partner Architect - IBM 118 | - Bethany Griggs - Sr. Software Engineer - Red Hat 119 | - Carlos Santana - Senior Technical Staff Member - IBM 120 | - Dominic Harries - Dev Lead at IBM Garage for Cloud 121 | - Jim Lindeman - Sr. Software Engineer - IBM 122 | - Joe Sepi - Open Tech Program Director - IBM 123 | - Lucas Holmquist - Sr. Software Engineer - Red Hat 124 | - Michael Dawson - Node.js lead for Red Hat and IBM 125 | - Noel Madali - Web Architect - The Weather Company at IBM 126 | - Tony Erwin - Senior Technical Staff Member - IBM 127 | - Wojciech Trocki - Software Engineer - Red Hat 128 | -------------------------------------------------------------------------------- /docs/assets/cors-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodeshift/nodejs-reference-architecture/37ed5147abc16cd7ddcda1a321fc348d1f51c619/docs/assets/cors-error.png -------------------------------------------------------------------------------- /docs/development/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Development", 3 | "position": 2 4 | } 5 | -------------------------------------------------------------------------------- /docs/development/accessibility.md: -------------------------------------------------------------------------------- 1 | # Accessibility 2 | 3 | In the context of software development accessibility refers to 4 | the use of assistive technologies to aid users in effectively 5 | using the software being developed. When designing interactions 6 | through the screen, keyboard, mouse, and speakers it is 7 | important to ensure that the widest possible group of users will be 8 | able to effectively participate in those interactions. 9 | 10 | For software developed with JavaScript the user interface (UI) typically 11 | falls into one of the following: 12 | 13 | 1) Browser based UI delivered though JavaScript, HTML and CSS. 14 | 1) Desktop type application built on something like 15 | [electron](https://www.electronjs.org/). 16 | 1) Command line scripts/applications. 17 | 18 | Both 1) and 2) above leverage JavaScript, 19 | HTML and CSS in a similar manner and we'll use 20 | web based applications to describe both of these. 21 | 22 | In web based applications, the HTML, JavaScript and CSS run 23 | in the browser (or equivalent in frameworks like electron) 24 | and is referred to as the front-end. The back-end running 25 | on Node.js provides the business logic to the front 26 | end through REST APIs, websockets or some other set of APIs. 27 | 28 | In this context, the focus on accessibility is in the 29 | development of the front-end as opposed to 30 | JavaScript running under Node.js in the back-end. 31 | 32 | ## Legal Requirements 33 | We have outlined above the moral obligation to ensure that our software is accessible. Many jurisdictions also mandate software accessibility by law. For example, in [Israel](https://www.gov.il/he/Departments/Guides/website_accessibility?chapterIndex=3), websites that offer a public service (to exclude, e.g. a private blog) must conform to WCAG 2.0 at the AA level, and businesses that do not comply may be liable for statutory damages. Another good example for requirements in the US public sector 34 | is the requirements related to [Section 508](https://www.section508.gov/). 35 | 36 | In order to find out about policies that may apply to your jurisdiction, this 37 | [page](https://www.w3.org/WAI/policies/) 38 | from the W3C provides a good starting point. 39 | 40 | ## Recommendation Components 41 | 42 | N/A 43 | 44 | ## Guidance 45 | 46 | The teams experience is that it is useful for organizations and teams 47 | building products or components with significant user interfaces to 48 | define guidelines and or design systems that apply to their product or organization 49 | and help ensure accessibility is planned in from the start. 50 | Examples of such guidelines which apply to the work of the team members include: 51 | 52 | * [IBM Accessibility requirements](https://www.ibm.com/able/requirements/requirements/) 53 | * [PatternFly accessibility guide](https://pf4.patternfly.org/accessibility-guide/) 54 | 55 | Developers may also use pre-made components with accessibility features built in: 56 | 57 | * [PatternFly React](https://github.com/patternfly/patternfly-react) 58 | * [Red Hat Design System](https://github.com/redhat-ux/red-hat-design-system/) 59 | 60 | Users should make sure to read and understand the accessibility documentation for pre-made components. 61 | It is also best practice to incorporate testing of your application with common 62 | assistive technologies like screen readers and limiting input to keyboard interaction. See [tooling](#tooling) below. 63 | 64 | For those working on Linux 65 | [List Of Accessibility Documentation Sources And Tools (For GNU/Linux Development And Testing)](https://desktopqe-jenkins.rhev-ci-vms.eng.rdu2.redhat.com:3200/desktopqe/d06-projects/a11y.A11y_devel_doc_sources.html) 66 | provides information on good starting points. 67 | 68 | ### Web based applications 69 | 70 | In web based applications most of the accessibility work is done in the front-end. The 71 | [Web Content Accessibility Guidelines (WCAG)](https://www.w3.org/TR/WCAG21/) is 72 | the recognized standard for making a web application accessible. The teams 73 | members have found the 74 | [WCAG quick reference](https://www.w3.org/WAI/WCAG21/quickref/) a useful 75 | reference for working with the guidelines. The [WAI-ARIA Authoring Practices Examples](https://www.w3.org/TR/wai-aria-practices/examples/) provide a comprehensive list of exemplary widgets complete with code snippets and live demos. 76 | 77 | In the teams experience testing/validation of accessibility requirements will be 78 | against the front-end and not the APIs provided by the Node.js back-end. The result 79 | being that team members building the front-end must be knowledgeable on 80 | accessibility requirements. Back-end Node.js developers, on the other hand, will support 81 | requirements that come from the front-end versus driving the accessibility effort. 82 | 83 | Server side rendering may blur the line a bit, but most often front-end developers 84 | or those with front-end skills should be involved in the development of 85 | the HTML that will be rendered on the server and the same guidelines apply as 86 | when rendered in the browser. 87 | 88 | In addition to supporting requirements driven by the front end, we recommend that 89 | Node.js developers: 90 | 91 | * build APIs in a way that avoids hard coding resources returned to the front end and 92 | ensuring they can provide all required forms of a resource. Resources required by 93 | the front-end may need an alternative form in order to support accessibility 94 | (For example alternative text for audio, etc.). 95 | * Ensure that error messages are understandable when read aloud. Error messages returned 96 | to users may be read by screen readers. 97 | 98 | As mentioned in later sections, some tools for accessibility testing are written 99 | in Node.js. As a result, Node.js developers may also be involved in helping to automate 100 | accessibility testing. 101 | 102 | ### Command line scripts/applications. 103 | 104 | Command line tools have been historically considered more accessible (see 105 | [Accessibility of Command Line Interfaces](https://dl.acm.org/doi/fullHtml/10.1145/3411764.3445544) 106 | for discussion on this topic). 107 | For this reason, most if not all of accessibility standards and guidelines are for 108 | graphical user interfaces. The team is not aware of standards or guidelines that 109 | provide guidance specifically for command line applications. 110 | 111 | If you integrate enhanced visual elements (for example color) into your 112 | command line interfaces, the team recommends that you review the corresponding 113 | sections of the web accessibility guidelines. 114 | 115 | [Accessibility of Command Line Interfaces](https://dl.acm.org/doi/fullHtml/10.1145/3411764.3445544) 116 | provides a number of good recommendations which are not specific to Node.js. These 117 | include: 118 | 119 | * Ensure that an HTML version of all documentation is available. 120 | * Provide a way to translate long outputs into another accessible format. 121 | * Document the output structure for each command. 122 | * Provide a way to translate tables in CLI output into another accessible format. 123 | * Ensure that all commands provide status and progress indication. 124 | * Ensure that all status and progress indicators used are screen reader friendly. 125 | * Ensure that error messages are understandable when read aloud. 126 | 127 | ### Tooling 128 | 129 | Accessibility tooling is generally not Node.js specific. However some tools are 130 | built in Node.js and are delivered through npm. They will, therefore, fit easily in a JavaScript 131 | or Node.js workflow when necessary. For example: 132 | * [eslint-plugin-jsx-a11y](https://www.npmjs.com/package/eslint-plugin-jsx-a11y) 133 | * [axe-core](https://www.npmjs.com/package/axe-core) 134 | * [pa11y](https://www.npmjs.com/package/pa11y) 135 | * [web test runner](https://modern-web.dev/docs/test-runner/overview/) and [open-wc testing helpers](https://open-wc.org/docs/testing/chai-a11y-axe/) provide framework-agnostic a11y unit testing tools. See [PatternFly Elements' ``](https://github.com/patternfly/patternfly-elements/blob/6363f03d2d95db5146eee6453330b919655fb034/elements/pfe-accordion/test/pfe-accordion.spec.ts#L449-L452) for an example of how to write keyboard accessibility tests for interactive widgets 136 | 137 | ## Further Reading 138 | 139 | [Introduction to the Node.js reference architecture: Accessibility](https://developers.redhat.com/articles/2022/11/03/nodejs-reference-architecture-part-10-accessibility) 140 | -------------------------------------------------------------------------------- /docs/development/ci-cd.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 14 3 | --- 4 | 5 | # CI/CD 6 | 7 | Based on common developer workflows as documented in the section titled 8 | [Typical Development Workflows](./dev-flows.md#typical-development-workflows) 9 | the end target/deployment artifact is often a container image. Most of our 10 | advice/recommendations are therefore in the context of building/testing 11 | one or more images. 12 | 13 | In the context of a Node.js component the version of the component and 14 | the version of Node.js used to run that component are managed through 15 | a Dockerfile to configure the version of the component and the base 16 | image to be used in a deployment. The base image may be an 17 | existing Node.js image (for example) 18 | [ubi8/nodejs-16](https://catalog.redhat.com/software/containers/ubi8/nodejs-16/615aee9fc739c0a4123a87e1) 19 | image or a [dependency image](./building-good-containers.md#dependency-image). 20 | 21 | While a Node.js developer may not need to setup the CI/CD pipeline a 22 | good understanding of their organizations pipeline is often valuable 23 | in order to understand what's needed to externalize configuration in 24 | the code they write as well as being able to investigate problems that 25 | may occur during different environments in the pipeline. 26 | 27 | ## Recommended Packages 28 | 29 | N/A 30 | 31 | ## Guidance 32 | 33 | The team's experience is that there are most often two different ci/cd flows 34 | which are used at the same time: 35 | 36 | * Testing on code check-in 37 | * Container pipeline - a pipeline to build and test images as they 38 | are promoted from development through to production. 39 | 40 | While tools like [Source to image](https://github.com/openshift/source-to-image), 41 | [docker](https://www.docker.com/) or [podman](https://podman.io/) maybe used by 42 | the developer to test locally as documented in 43 | [Fully local development, container based](./dev-flows.md#fully-local-development-container-based) workflow, 44 | the developer does not push the image to source control. Instead, 45 | the images used for deployment are build as part of the container pipeline. 46 | 47 | ## Testing on code check-in 48 | 49 | When a PR is made against a main branch in a source code repository (most often 50 | some form of git these days) initial testing is automatically kicked off 51 | using services like [Travis CI](https://www.travis-ci.com/) or 52 | [GitHub actions](https://github.com/features/actions). This level of testing 53 | starts with `unit` and `code quality` testing and the teams recommendations 54 | for this kind of testing for Node.js components are captured in the 55 | [Code Consistency](./code-consistency.md), 56 | [Testing](./testing.md), and 57 | [Code Coverage](./code-coverage.md) sections. Teams often 58 | then also test the PR by spinning up a container environment and running some 59 | initial integration test. If you run check-in integration tests it is often useful to run both 60 | integration and unit tests in the container in order to capture a more complete picture 61 | of the Code Coverage achieved. 62 | 63 | When a PR lands in the source code repository after passing 64 | those checks, the pipeline for building and testing images 65 | may be triggered automatically or it may be triggered separately 66 | at some interval. 67 | 68 | Check-in testing is often configured to run on a number of Node.js 69 | versions in parallel and the team recommends that you test at least on the 70 | LTS version of Node.js that you currently deploy with along with 71 | later LTS versions in order to enable future upgrades. 72 | 73 | While the check-in testing may not run on the image that flows 74 | through the container pipeline, the team tries to ensure 75 | that testing is on the same environment/architecture as used 76 | by the container pipeline. In addition, the team also recommends 77 | that the same is true for local testing done by developers. 78 | 79 | ## Container Pipeline 80 | 81 | Once updates have passed the initial check-in testing, the container 82 | pipeline is kicked off. In the teams experience the pipeline may 83 | support a number of stages/environments including: 84 | 85 | * Development 86 | * This environment often mirrors the main branch of each component 87 | and may sometimes not be working due to mismatches in APIs/use of APIs. 88 | * Once tests pass in development, PRs may be automatically opened to 89 | update Staging to the new component levels. 90 | * Staging 91 | * Staging uses tagged versions of each component which are known to 92 | work together. 93 | * They may be multiple staging environments. One which 94 | mirrors production in terms of non-application components 95 | (versions of Istio, Kubernetes, etc.) and additional 96 | environments which reflect future target configurations 97 | for these components. 98 | * PRs may be automatically created to update component versions in 99 | production once tests pass in Staging but there is most often a 100 | formal sign off (by QA or other teams) for these to be accepted 101 | into production. 102 | * Pre-Production (optional) 103 | * pre-production may be used to allow customer testing/sign 104 | off before push to production. 105 | * Some teams use Staging instead of having a separate pre-production 106 | environment. 107 | * Production 108 | * Environment that hosts the customer facing service. 109 | 110 | In addition to these environments, the team has also found that supporting 111 | the ability to spin up ephemeral environments to do specific testing when 112 | needed is advantageous. 113 | 114 | The version of the component and the version of Node.js (through the base 115 | container image used) is fixed in the Development stage of the pipeline 116 | where the image is built for the component. That image is typically 117 | pushed to an internal registry and later steps in the pipeline use a tagged 118 | version of that image from the registry. 119 | 120 | As the image for the Node.js component is built once and promoted 121 | through the pipeline stages, it is important that all configuration 122 | related to the environment is externalized so that environment specific 123 | values can be provided in each environment. This includes for example 124 | configuration for how to connect to databases and other services, the 125 | Node.js run configuration (production/development) and any other configuration 126 | information. 127 | 128 | [Jenkins](https://www.jenkins.io/) and 129 | [Tekton Pipelines](https://tekton.dev/) are common tools that have been 130 | used by the team to implement the container pipeline. 131 | 132 | The team has found that it is advisable to use a separate git repository/branch 133 | to configure the versions of the components to be tested in each environment 134 | within the container pipeline. One common pattern the team has seen is using 135 | helm charts within this repo to configure the versions of the components used 136 | along with the configuration required for a given environment. 137 | 138 | The team has found that it is useful to have shared helm charts for common application 139 | categories, deploying them helm parameters. In addition the team has also found 140 | it useful to separate configuration of the component versions from other 141 | configuration which does not change as often. This helps to isolate other 142 | changes from the more common component version changes. 143 | 144 | ## Security scans 145 | 146 | Security checks are an important part of CI/CD pipelines. Typically the team 147 | deploys code and image scans in the check-in tests and/or the container pipeline. 148 | The benefit of running in the check-in tests helps developers validate that 149 | they have resolved reported issue. 150 | deploys checks in both the check-in tests as well as the container pipeline. 151 | 152 | Tools like [mend](https://www.mend.io/), [Snyk](https://snyk.io/) and those 153 | built into GitHub have been used for scanning in the check-in phase. Often 154 | a number of different scans are required to cover all of the important aspects 155 | which include scans of: 156 | * application dependencies for vulnerabilities 157 | * os packages for vulnerabilities 158 | * source code using static analysis 159 | * container images for best practices (not running as root etc.) 160 | 161 | Additional image based scans are then employed in the piplelines phases. 162 | 163 | -------------------------------------------------------------------------------- /docs/development/code-consistency.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Code Consistency 6 | 7 | It is important to the efficiency of teams working 8 | on JavaScript (and other languages) to have consistency 9 | in formatting within the projects managed by their team. 10 | 11 | Not having a consistent coding style documented or enforcing 12 | consistency manually as part of code reviews or 13 | other manual techniques is error prone, potentially 14 | harmful to relationships between team members, 15 | is a barrier to attracting external contributions and can 16 | result in bugs because the is harder to understand and spot 17 | repeating patterns. 18 | 19 | Consistency should be enforced through automated tooling 20 | which is well integrated into the process of landing 21 | Pull Requests (or equivalent). 22 | 23 | There are benefits to consistency across an organization but 24 | it is also important that teams are empowered to do what is 25 | right for their projects. We recommend starting with an 26 | organizational standard and then adjusting based on the 27 | needs of the team. 28 | 29 | ## Recommended Components 30 | 31 | - ESLint - https://eslint.org/ 32 | 33 | ESLint is broadly used with the `teams` organizations and has broad usage 34 | across the JavaScript ecosystem with > 11 million weekly downloads. 35 | It can be configured to reflect the coding style followed by most 36 | if not all teams. 37 | 38 | # Guidance 39 | 40 | - Use one of the pre-existing ESLint shareable configurations. There are a number 41 | of pre-existing configurations and re-using one of these has a number 42 | of benefits: 43 | 44 | - minimizing what can be potentially divisive discussions to agree 45 | on the style to be followed. 46 | - leveraging the experience of what has worked for other teams. 47 | - increasing the likelihood of familiarity for new team members. 48 | 49 | Examples include: 50 | 51 | - eslint-config-airbnb-standard - https://www.npmjs.com/package/eslint-config-airbnb-standard 52 | - eslint-config-semistandard - https://www.npmjs.com/package/eslint-config-semistandard 53 | - eslint-config-standard - https://www.npmjs.com/package/eslint-config-standard 54 | - eslint-config-prettier - https://github.com/prettier/prettier-eslint 55 | 56 | with a complete list available through this query: https://www.npmjs.com/search?q=eslint-config-&ranking=popularity 57 | 58 | - Integrate eslint into your package.json so that it runs before scripts. For example: 59 | 60 | ```json 61 | "scripts": { 62 | "pretest": "eslint --ignore-path .gitignore ." 63 | } 64 | ``` 65 | 66 | - set your project to extend your chosen eslint-config-X by populating an eslintrc.json file: 67 | 68 | ``` 69 | echo '{"extends": "X"}' > .eslintrc.json 70 | ``` 71 | 72 | substituting X with your chosen config. You can also get started by running `npx eslint --init` which 73 | will ask you a number of interactive questions and then create your `.eslintrc.json` file and add 74 | the required dependencies into your package.json. 75 | 76 | - Ensure you have a gitignore file so derived files do not get linted. A minimal one can be 77 | created with: 78 | 79 | ```shell 80 | echo node_modules/ >> .gitignore 81 | ``` 82 | 83 | Some additional useful suggestions are available in this 84 | [article](https://medium.com/the-node-js-collection/why-and-how-to-use-eslint-in-your-project-742d0bc61ed7). 85 | 86 | - When adopting a pre-existing shareable config it is important to understand that these 87 | configs can change over time. Include time in your regular workflow to review these changes 88 | and update your code base appropriately. 89 | 90 | - Configure hooks to run eslint before committing code, but ensure that this pre-commit check does not take too long to execute which may cause complaints from developers. 91 | 92 | - Use [husky](https://github.com/typicode/husky) to configure scripts to run before git commits and git pushes. 93 | - These checks can be skipped by a developer when needed via `git commit --no-verify` 94 | - Use [lint-staged](https://github.com/okonet/lint-staged) to reduce amount of code to be linted. This speeds up linting step before commit/push. 95 | These can be integrated into package.json as follows: 96 | 97 | ```json 98 | "lint-staged": { 99 | "**/*.js": "eslint" 100 | }, 101 | "husky": { 102 | "hooks": { 103 | "pre-commit": "lint-staged" 104 | } 105 | } 106 | ``` 107 | 108 | - Always ensure CI/CD is running linting regardless of hooks. 109 | 110 | ## Further Reading 111 | 112 | [Introduction to the Node.js reference architecture: Code Consistency](https://developers.redhat.com/articles/2021/05/17/introduction-nodejs-reference-architecture-part-3-code-consistency) 113 | -------------------------------------------------------------------------------- /docs/development/code-coverage.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 7 3 | --- 4 | 5 | # Code Coverage 6 | 7 | Code coverage is a software testing metric that determines the number of lines of code that is successfully validated under a test procedure, which in turn, helps in analyzing how comprehensively a software is verified. 8 | 9 | To measure the lines of code that are actually exercised by test runs, various criteria are taken into consideration. Outlined below are a few important coverage criteria are used. 10 | 11 | Function Coverage – The functions in the source code that are called and executed at least once. 12 | 13 | Statement Coverage – The number of statements that have been successfully validated in the source code. 14 | 15 | Path Coverage – The flows containing a sequence of controls and conditions that have worked well at least once. 16 | 17 | Branch or Decision Coverage – The decision control structures (loops, for example) that have executed fine. 18 | 19 | Condition Coverage – The Boolean expressions that are validated and that executes both TRUE and FALSE as per the test runs. 20 | 21 | 22 | ## Recommended Modules 23 | 24 | - [nyc][]: the most popular code-coverage tool; the successor CLI for Istanbul 25 | - [jest][]: Code coverage using the `--coverage` flag 26 | 27 | # Guidance 28 | 29 | ## Where to focus on higher coverage 30 | 31 | For applications, the coverage should be driven by the key user stories/key paths that the application can take. For modules, it is important to cover all public APIs. 32 | 33 | 34 | 35 | ## Coverage percentage thresholds 36 | 37 | For those projects that are new, and just starting out, a good percentage threshold is about 70%. This is because with new projects, it is easier to add tests while creating the application. 38 | 39 | 40 | If adding coverage to a project that is older that might not have any coverage yet, it might be a little harder since adding tests to an older project with technical debt can be a challenge, especially for someone new coming into the project. In this case a good percentage threshold is about 30%. It is also our experience that when adding coverage to a older code base, focusing on the key user stories will give you the best return on investment. Focusing on the Path and/or Branch/Decision coverage will also maximize the investment on getting to 30%. 41 | 42 | 43 | ## OpenSource Projects 44 | 45 | For OpenSource projects, it might be helpful to post the results of the coverage to an external service, such as coveralls and creating an issue related to increasing the code coverage could be a way to attract contributors to the project. 46 | 47 | It is also common to report the coverage increase or decrease percentage during a PR CI run. In our experience, it is best to use this information in a code review rather than blocking a merge. 48 | 49 | Code coverage should never block a production deployment 50 | 51 | 52 | ## Output Formats 53 | 54 | A common output format is the lcov format, which the recommended modules can produce. 55 | 56 | [jest]: https://www.npmjs.com/package/jest 57 | [nyc]: https://www.npmjs.com/package/nyc 58 | 59 | 60 | ## Further Reading 61 | 62 | [Introduction to the Node.js reference architecture: Choosing Web Frameworks](https://developers.redhat.com/articles/2022/03/02/introduction-nodejs-reference-architecture-part-7-code-coverage) 63 | -------------------------------------------------------------------------------- /docs/development/cross-origin.md: -------------------------------------------------------------------------------- 1 | # Cross Origin Communication 2 | 3 | 4 | ## Guidance 5 | 6 | There are two patterns that the team is familiar with when dealing with Cross Origin Communication. Those are Cross Origin Resource Sharing(CORS) and using a Proxy server. 7 | 8 | ## Cross Origin Resource Sharing (CORS) 9 | 10 | By default, browsers assume that your backend server doesn't want to share its resources with a front-end that it doesn't know about. 11 | 12 | You might have seen this error in the browsers dev console: 13 | 14 | ![cors error from chrome dev tools](../assets/cors-error.png) 15 | 16 | We have a [small and simple application](https://github.com/nodeshift-blog-examples/cors-ref-arch-demo) that demonstrates getting a CORS error and how to fix it. 17 | 18 | However, there are certain situations where your backend might want to be accessible to a front-end application, like a website, CORS should be enabled. Listed below are some situations, where you might want to make sure CORS is enabled 19 | 20 | ### External APIs 21 | 22 | When developing a backend with a public API and you would like to control access to certain resources and how they are used, CORS should be enabled. 23 | 24 | **note: When enabling CORS, it is important to limit those methods and headers your application allows to prevent unwanted actors from accessing resources they shouldn't be accessing.** 25 | 26 | 27 | ### Access to Multiple Environments 28 | 29 | As part of the development and testing process of a front-end application, you might want to test against multiple environments, like staging and pre-productions, before pushing to production. If CORS is not enabled on each of these backends, the front-end application will fail to communicate with them. 30 | 31 | The team recommends using environment variables to control allowed origin hosts. This allows keeping CORS enabled locally, but provides different values for each environment. 32 | 33 | ## Proxy Server 34 | 35 | The team also has experience doing cross origin communication using a Proxy Server. 36 | 37 | This is helpful when you can't make requests directly from your front-end application to the API server. Your front-end application might only be able to make requests to its host server. The host server would then proxy those requests to the target API server. 38 | 39 | ## Recommended Components 40 | 41 | [cors](https://www.npmjs.com/package/cors) is a node.js package for providing a Connect/Express middleware that can be used to enable CORS with various options. 42 | 43 | Most web frameworks, like express.js, have [similar modules](https://www.npmjs.com/search?q=cors) to help easily enable and manage CORS requests 44 | 45 | ## Further Reading 46 | 47 | * [cors](https://www.npmjs.com/package/cors) 48 | 49 | * [CORS module search on npm](https://www.npmjs.com/search?q=cors) 50 | 51 | * [CORS on mdn](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) 52 | -------------------------------------------------------------------------------- /docs/development/dependencies.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 7 3 | --- 4 | # Choosing and vetting dependencies 5 | 6 | Node.js applications and modules often use a number of third party 7 | dependencies. It is important that you choose those dependencies 8 | carefully and regularly validate that they continue to be good 9 | choices. 10 | 11 | ## Recommended Components 12 | 13 | N/A 14 | 15 | ## Guidance 16 | 17 | Based on the teams experience we recommend the following: 18 | 19 | * Check what is already being used within your organization. Your 20 | organization may already have a reference architecture or something 21 | similar that can help you find modules that your organization has 22 | already had a good experience with or decided are good choices. 23 | * Limit dependencies to the minimum required 24 | * prefer dependencies with limited or no dependencies of their own 25 | * avoid one-liners, is using the modules really saving you time 26 | development/maintenance time versus incorporating your own code? 27 | * Prefer dependencies that already have a reasonable level of usage 28 | based on github star count and npm usage count. Compare usage 29 | to other possible options. 30 | * Prefer dependencies with an active, open, and inclusive community. 31 | Note that in some cases a dependency may be "done" but open and 32 | inclusive is still important in those cases. Some 33 | indicators to consider include: 34 | * Number of active contributors since inception 35 | * If you needed to contribute a fix would it be accepted? 36 | * How long does it take for CVEs to get addressed? 37 | * Do you have to move up to a new Major release to get security fixes? 38 | * What is the cadence of releases? 39 | * Is the project part of a larger project or Foundation? 40 | * Prefer dependencies aligned with the Node.js project releases 41 | * Does it support the current Node.js LTS releases 42 | * Is the dependency tested by the Node.js project's 43 | [Canary in the Gold Mine](https://github.com/nodejs/citgm)? 44 | * If the dependency is a native module does it use Node-API (use 45 | of Node-API means that packages can work across Node.js major versions) 46 | * Only use dependencies with licenses acceptable to your organization 47 | * When choosing to use dependencies with a lower level of use in the 48 | ecosystem doing a code review to look for red flags can be useful. 49 | 50 | When evaluating dependencies, the teams typically evaluate the top level 51 | dependencies versus the full tree **EXCEPT** for the following in which 52 | we evaluate the full tree: 53 | * License Checks 54 | * Security vulnerabilities (CVEs) 55 | Total number of sub-dependencies 56 | 57 | The Red Hat Node.js team is currently using 58 | [npcheck](https://github.com/nodeshift/npcheck) 59 | to help review packages based on some of the suggestions above. 60 | -------------------------------------------------------------------------------- /docs/development/dev-flows.md: -------------------------------------------------------------------------------- 1 | # Typical Development Workflows 2 | 3 | Development flows within the team's developer and the customers the team works 4 | with need to accommodate the following: 5 | 6 | * the end target/deployment artifact is most often a container 7 | * for some platforms, deployment remains a server or virtual machine 8 | * applications are made of multiple components some of which may be being developed 9 | by other teams. 10 | 11 | The typical development flows encountered by the team include: 12 | 13 | * Fully local development 14 | * Fully local development, container based 15 | * Local development of team's component, remote services in a common development environment 16 | * Fully remote development, container based. 17 | * Zero install development environment 18 | 19 | Regardless of the development flow, developers typically develop on Windows or MacOS with Linux being 20 | distant third. When running on Windows the trend is towards the use of the Windows Subsystem for Linux. 21 | 22 | With developers developing on Windows/MacOS and the deployment target most often being Linux in 23 | a container, the team's experience is that it is important for the developer to do some level of 24 | testing in a container as part of their workflow. 25 | 26 | In the past the most common approach for building/running containers on Windows and MacOS 27 | was docker desktop. Now that docker desktop is no longer free, development teams are exploring other 28 | 29 | options which include: 30 | * Virtualbox with a linux VM (the disadvantage is that this requires developers to become more 31 | familiar with Linux). Docker client is still free and it can connect to a remove virtual 32 | machine. 33 | * podman and podman desktop which provides similar functionality to docker desktop but is 34 | open source and free. 35 | 36 | ## Fully local development, native platform 37 | 38 | Developers build/test in the local environment (Windows/MacOS) using npm start and once 39 | ready push to CI where the target container or server deployment bundle is built. Testing 40 | with other components is limited to test/integration environments. Any local testing 41 | uses mocks for other components. 42 | 43 | This is a common starting point when teams are building a simple application, with a limited 44 | number of components that can be easily moc'd or run locally. 45 | 46 | Advantages: 47 | * Easy to set up 48 | 49 | Disadvantages: 50 | * native testing means problems due to difference between operation on development 51 | platform (Windows/MacOS) and deployment platform (Linux/container) are not 52 | discovered until later in the integration test environment. 53 | * problems related to interaction with other components is not discovered until later 54 | in the integration test environment 55 | 56 | ## Fully local development, container based 57 | 58 | Developers build/test/integrate in containers and run other components in containers 59 | locally. Kubernetes is often used to run containers along with Helm to spin up other 60 | components needed for testing. Docker compose is another approach that the team 61 | sees being used to run other components in containers within the local environment. 62 | 63 | In both cases a mounted file system is often used to allow live 64 | changes to a running container with strategies like nodemon style watching and 65 | kubectl copy. 66 | 67 | Advantages: 68 | * problems related to differences in development(Windows/MacOS) and deployment 69 | target (Linux container) are found earlier in the development process. 70 | * Problem related to interaction with other components are discovered earlier 71 | in the development process. 72 | * No need for network access in order while developing/testing 73 | * Easier to manage and test against different application dependency versions 74 | as they are managed locally instead of a shared environment and often have easy to 75 | use docker image tags. 76 | 77 | Disadvantages: 78 | * more complex to setup and manage for each developer 79 | * significant developer machine requirements to run kubernetes and other components 80 | * harder to manage configuration drift between development environment and 81 | deployment environment because the container infrastructure used on the developers 82 | workstation often different than that used for production deployment. 83 | 84 | ## Local development of team's component, remote services in a common development environment 85 | 86 | Developers build/test/integrate in containers and access other components for 87 | testing in a shared development/test environment. 88 | 89 | Advantages: 90 | * More limited resource requirement for developer machines 91 | * Less management/complexity for developers 92 | 93 | Disadvantages: 94 | * Network connectivity is required to develop 95 | * Harder to explore/test out changes needed in other components to support 96 | the component you are working on 97 | * Concurrent use of of shared development/test environment running other 98 | services can add need for co-ordination with other developers/teams. 99 | * There may be more limited access to containers when running in the 100 | shared environment, making it harder to debug. 101 | 102 | ## Fully remote development, container based 103 | 104 | Developers build/test/integrate in containers by pushing changes which are built and 105 | tested in a kubernetes environment which is also running the other required components. 106 | Developers often run some limited test with npm start but bulk of testing is done 107 | on remote system. 108 | 109 | Advantages: 110 | * Limited resource requirements for developer machines 111 | * Less management/complexity for developer 112 | * Easier to keep development and deployment environments in sync 113 | 114 | Disadvantages: 115 | * Network connectivity is required to develop 116 | * Time to push changes can affect iteration time 117 | * Each developer requires sandbox in common kubernetes, adding to management 118 | complexity and resource requirements. 119 | * Cleanup of non-used resources can be a challenge 120 | 121 | ## Zero install development environment 122 | 123 | Developers use a virtualized remote environment and use their local laptop 124 | only as a thin client. 125 | 126 | This model is typically an extension to one of the other 127 | development models listed, with the difference being where the code being 128 | developed resides/is created by the developer. For example, as an extension 129 | to the fully local development workflow the developer may use a 130 | remote virtual machine instead of developing directly on their laptop. 131 | As another example, as an extension to the fully remote development workflow a 132 | shared development environment may provide UI's to edit code, build 133 | containers and deploy to a shared kubernetes environment. 134 | 135 | The most extreme case of this model is to limit access to a Cloud based IDE 136 | which restricts the functionality available to the developer. 137 | 138 | As a baseline this approach inherits the advantages/disadvantages of 139 | the underlying model that it extends. 140 | 141 | Additional Advantages: 142 | * Easier setup 143 | * Better control for an organization over the development environment 144 | and code being developed 145 | * Supports organizations that use a perimeter security model 146 | 147 | Additional Disadvantages: 148 | * Additional resources are required 149 | * Cleanup of non-used resources can be a challenge 150 | * High dependency on network connection 151 | * Cloud IDEs tend to be more locked down, giving developers less 152 | flexibility over development workflow and tools 153 | 154 | ## Further Reading 155 | 156 | [Introduction to the Node.js reference architecture: Typical development workflows](https://developers.redhat.com/articles/2022/12/21/typical-development-workflows) 157 | -------------------------------------------------------------------------------- /docs/development/mono-repository.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 7 3 | --- 4 | 5 | # Mono-Repository (monorepo) Tooling and Guidance 6 | 7 | Working across multiple repositories for the same project and/or team is cumbersome and slows down developer velocity. A way to improve developer velocity for teams and projects is to leverage a mono-repository (monorepo). With a monorepo, teams will be able to maintain multiple packages in a singular repository without having to switch to different repositories to maintain other packages. A monorepo may not be only JavaScript, and can be a mixture of languages. For example, a monorepo can contain JavaScript, TypeScript, Golang, Python, etc. A monorepo could also be scoped per team or project, meaning any project could belong in a monorepo, or a monorepo could be exclusively scoped for a particular project. As an example, [babel][babel] is a monorepo for babel, whereas Google has an entire monorepo for the company. 8 | 9 | ## Recommended Packages 10 | 11 | To enable a mono-repository, we recommend leveraging [yarn workspaces][yarn-workspaces] or [npm workspaces][npm-workspaces]. 12 | 13 | ### Setup with Yarn Example 14 | 15 | #### Modify package.json in the workspace root 16 | 17 | ``` 18 | { 19 | "private": true, 20 | // this is an array containing glob paths to each workspace 21 | "workspaces": ["workspace-a", "packages/*"] 22 | } 23 | ``` 24 | 25 | #### Create subfolders and package.json for each package in the monorepo 26 | 27 | ``` 28 | // /workspace-a/package.json 29 | { 30 | "name": "workspace-a", 31 | "version": "1.0.0", 32 | "dependencies": { 33 | "foo": "0.0.1" 34 | } 35 | } 36 | 37 | // /packages/foo/package.json 38 | { 39 | "name": "foo", 40 | "version": "1.0.0" 41 | } 42 | ``` 43 | 44 | #### Run `yarn install` in the workspace root 45 | 46 | 47 | Given the above, we should expect the following folder structure 48 | ``` 49 | /package.json 50 | /yarn.lock 51 | /workspace-a/package.json 52 | /packages/foo/package.json 53 | /node_modules 54 | /node_modules/workspace-a -> /workspace-a 55 | ``` 56 | 57 | ## Guidance 58 | 59 | There are a handful of benefits and challenges to monorepos. 60 | 61 | With a monorepo, it is recommended to leverage a common set of tooling for [linting][linting] and [testing][testing] across all packages in the repository. See our [code-consistency][code-consistency] section for further guidance. Having a common set of tooling is a benefit for monorepos since each package managed in the repo does not need its set of tooling or versioning. On the other hand, teams can also control scripts individually per artifact or package if necessary. See `Advanced Tips / Tricks` section for more details. 62 | 63 | While there are a benefits, there are challenges to overcome. 64 | 65 | * Detecting what to build. Build times can be long due to overbuilding the entire repository 66 | * Long build times. Because of having to build the entire repository, this will cause build times to increase because tooling no longer is just building one artifact/package, but many different ones. 67 | * Not just JavaScript. A monorepo may not just be JavaScript, and can impact organization, tooling, and how to approach building different artifacts or packages in different languages. 68 | * Git repositories can grow larger in size. Since we are building and maintaining different packages in a singular repository, we can exponentially grow the size of the git repository. 69 | * Commit messages can be harder to interpret due to multiple artifacts, packages, or teams. 70 | 71 | 72 | ### Building 73 | 74 | When building npm packages (or any type of package) (the build) in the monorepo, we have had success using: 75 | 76 | * [bazel][bazel] 77 | * Custom scripts 78 | 79 | Using appropriate build tools help overcome challenges state previously. With build tools, we are able to detect file changes and build the appropriate artifact/packages necessary without building the entire repository. This helps reduce long build times. Having a good build tool like [bazel][bazel] also allows for potential to build out other project artifact/packages in different languages. 80 | 81 | When committing messages, teams can utilize [conventionalcommits][conventionalcommits] to reduce confusion when working on a monorepo. 82 | 83 | #### Bazel 84 | 85 | We use the Bazel to support multiple programming languages and to determine what components have to be compiled and tested based on source code changes. 86 | 87 | #### Custom Scripts 88 | 89 | For custom scripts, we leverage Shell Scripts, Makefiles, JS, and Golang tooling to detect changes and build packages and services. 90 | 91 | ### Publishing 92 | 93 | If you are working with a set of packages that need to be published, you can leverage: 94 | 95 | * [changesets][changesets] 96 | 97 | About [lerna][lerna]: Lerna was previously used but because of [yarn workspaces][yarn-workspaces] and [npm workspaces][npm-workspaces], teams have no longer found a need for [lerna][lerna] 98 | 99 | #### Package Releasing 100 | 101 | We recommend following semantic versioning across all packages. If a change does not impact all packages, then bump the appropriate minor/patch version as necessary. 102 | 103 | For example, if a Package A needs security remediation, and Package B does not, simply increment patch version for Package A. 104 | 105 | If you are making a breaking change that is across all packages, apply major version to all packages. 106 | 107 | #### Service Releasing 108 | 109 | Service releasing is treated differently than publishing since services are released not for package consumption but as a service. 110 | 111 | Dependent upon deployment strategy, releases could be tagged differently per change or as an entire set (version of the repository). 112 | 113 | [yarn-workspaces]: https://classic.yarnpkg.com/lang/en/docs/workspaces/ 114 | [npm-workspaces]: https://docs.npmjs.com/cli/v7/using-npm/workspaces 115 | [lerna]: https://github.com/lerna/lerna 116 | [babel]: https://github.com/babel/babel 117 | [code-consistency]: ./code-consistency.md#guidance 118 | [changesets]: https://github.com/atlassian/changesets 119 | [semantic-release]: https://github.com/semantic-release/semantic-release 120 | [bazel]: https://bazel.build/ 121 | [linting]: ./code-consistency.md 122 | [testing]: ./testing.md 123 | [conventionalcommits]: https://www.conventionalcommits.org/en/v1.0.0/ 124 | -------------------------------------------------------------------------------- /docs/development/npm-proxy.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Npm Proxy / Internal Registry 6 | 7 | The npm registry is a key part of the node(and Javascript) ecosystem. It allows users to install third-party easily with just a few commands. But what happens when you are part of an organization that limits internet access, or you are worried that a module you use might disappear from the public registry. This is where having a layer between your organization and the public npm registry can help. This is commonly referred to as a npm mirror/npm proxy 8 | 9 | ## Recommended Components 10 | 11 | The _team_ has familiarity with using both Artifactory and Sonatype Nexus. Both have free and enterprise grade tiers available. 12 | 13 | ## Guidance 14 | 15 | It is recommended to use a Proxy/Mirror when possible. There are a few different reasons why you might consider this. 16 | 17 | - You need to limit the installation of modules to only a specific set. 18 | 19 | - If you have limited network access 20 | 21 | - Using a proxy/mirror can provide a centralized point for scanning for security vulnerabilities 22 | 23 | - A mirror can reduce the dependency on the public registry. 24 | 25 | - You need to maintain a copy of a module incase it is removed from the public registry. 26 | 27 | - Being a good npm citizen. The public registry is a free service and npm allows for [update to 5 million requests per month](https://blog.npmjs.org/post/187698412060/acceptible-use), which can be used up quickly with CI builds. 28 | 29 | Using a npm mirror/proxy is fairly easy. You can set the _registry_ that the npm cli uses by running `npm set registry URL`. 30 | 31 | Since these registry are not Node.js specific and can be used by other languages, organizations might already have something running where npm support can be turned on. 32 | 33 | ## Further Reading 34 | 35 | * [Introduction to the Node.js reference architecture: Node Module Development](https://developers.redhat.com/articles/2023/02/22/installing-nodejs-modules-using-npm-registry) 36 | 37 | * https://jfrog.com/artifactory/ 38 | 39 | * https://guides.sonatype.com/repo3/quick-start-guides/proxying-maven-and-npm/ 40 | 41 | * https://www.sonatype.com/products/repository-oss-vs-pro-features 42 | -------------------------------------------------------------------------------- /docs/development/npm-publishing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Npm Publishing Guidelines 6 | 7 | ## Guidance 8 | 9 | When publishing modules to npm, it is recommended to enable 2 factor authentication. How to set that up can be found here https://docs.npmjs.com/configuring-two-factor-authentication. It is also a good practice to require the use of two-factor authentication or automation tokens for each module that is published. 10 | 11 | If the module will be maintained by a group of people, it is better to create an organization for your team/project on npm to make it easier for multiple maintainers to manage and publish the package. 12 | 13 | It is also a good practice to have a "prepublish" npm script in the package.json that runs linting and tests before publishing happens. If your code needs to be transpiled first, having a "prepublish" script will make sure this is also done before publishing. 14 | 15 | The use of scoped packages is a good practice if you are creating many related packages. 16 | 17 | When creating modules that will be published to an internal registry that is not upstream npm, it is a good practice to scope those modules to the name of your organization. It is also important that you or your company are the owners of the scoped organization on upstream npm. This is important if a public module which depends on a private module is accidentally published to upstream npm, which can lead to the "Dependency Confusion" hack that is outlined [in this post](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610) 18 | 19 | ## Publishing Modules 20 | 21 | ### Preparing Code 22 | 23 | #### `.npmignore` or `files` 24 | 25 | [npm] has default ignore rules and loads from `.gitignore` but it also offer two methods for you to keep your published packages tidy. 26 | 27 | - specifying ignore files in `.npmignore` 28 | - specifying files you only want to publish with `files` in your `package.json`. 29 | 30 | Which one to go with is solely up to you and your preference. 31 | 32 | #### Tests and Docs 33 | 34 | For your tests and any extra documentation, like API reference docs, that goes beyond the packages README, you can choose to publish them or not. For modules that the team publishes we: 35 | 36 | - include docs 37 | - exclude tests 38 | 39 | Not including these files can decrease the size of the package that is being installed. If the source code for the package is hosted on github, it is a common practice to use github pages to host any API reference docs and provide a link to those in the README and the package.json. 40 | 41 | #### Transpiling Sources 42 | 43 | A package written in another language like TypeScript should be published with transpiled JavaScript as the primary executable. 44 | 45 | Generally the original sources should not be required to use your published package, but it's your preference whether to publish them or not. Similar to the guidance on tests, the modules that the team publishes that are transpiled only contain the generated code. 46 | 47 | If your module requires build steps, it is recommended to run those before you publish and not when the user installs the package. This is where you would use the `prePublish` script as mentioned above. 48 | 49 | It is important if you are using Typescript or are generating type definitions for your package, that you make sure to add a reference to the generated type file in your package.json and ensure that the file is included when publishing. For Example: 50 | 51 | ``` 52 | "name": "some_module", 53 | "description": "A module that does something", 54 | "main": "./bin/index.js", 55 | "module": "index.js", 56 | "types": "types/index.d.ts" 57 | ``` 58 | 59 | #### Module Versions 60 | 61 | It is recommended to use [Semantic Versioning](https://semver.org/) when possible. This will make it easier for a user to determine if a new version of a module will potentially break their code. 62 | 63 | There are some automation tools that can help with bumping your module to the correct version. 64 | 65 | - [release-please](https://github.com/googleapis/release-please) 66 | - [standard-version](https://github.com/conventional-changelog/standard-version) 67 | 68 | Both of those tools will base the version bump on commit messages that follow the [conventional commit standard](https://www.conventionalcommits.org/en/v1.0.0/) 69 | 70 | The npm cli also provides a [`version` command](https://docs.npmjs.com/cli/v7/commands/npm-version) that can be used to increase the version of package. 71 | 72 | #### Publish Internal Modules 73 | 74 | When publishing to an internal registry, like Artifactory or Nexus, it is recommended to scope your package. This adds extra protection if this module is accidentally published to a public registry and avoids the dependency confusion hack mentioned above. 75 | 76 | How to publish to an internal registry is up to you, but the team recommends the usage of a `.npmrc` file. 77 | 78 | A `.npmrc` file can also be used either per project or globally to change the registry that your package is published to. The contents of this file might look something like this: 79 | 80 | ``` 81 | registry=http://my-internal-registry.local 82 | ``` 83 | 84 | If you are using the global `.npmrc` file, you can use the [npmrc module](https://www.npmjs.com/package/npmrc) to easily switch between multiple `.npmrc` configurations, although it is not necessary for publishing to an internal registry. 85 | 86 | ## Further Reading 87 | 88 | * [Introduction to the Node.js reference architecture: Node Module Development](https://developers.redhat.com/articles/2023/02/22/installing-nodejs-modules-using-npm-registry) 89 | 90 | * https://github.blog/changelog/2020-10-02-npm-automation-tokens/ 91 | 92 | * https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610 93 | -------------------------------------------------------------------------------- /docs/development/protecting-code.md: -------------------------------------------------------------------------------- 1 | # Protecting Code 2 | 3 | Within some organizations (including IBM) there are requirements 4 | to protect source code. 5 | 6 | The motivations that have been mentioned include: 7 | 8 | * protection of intellectual property by making it harder for the 9 | code to be copied. 10 | * making it easier to pursue those who copy it by ensuring 11 | it takes more than casual/accidental access to the code to see it. 12 | * reducing exposure to liability by limiting analysis of the 13 | code. 14 | * making it harder for hackers to find/exploit vulnerabilities 15 | in the code. 16 | 17 | The preferred approach to protect source code is most often 18 | by shipping binaries after the source code has been compiled. 19 | This is not an option for JavaScript (without extreme effort 20 | for front-end JavaScript and significant effort for server side JavaScript) 21 | and `obfuscation` is typically used instead. 22 | 23 | Only source code that is available to customers or end users needs 24 | to be protected. Front-end JavaScript is almost always available 25 | to end users and while less common, back-end JavaScript may be 26 | available to customers when it is included in products that 27 | are sold to and run by customers. 28 | 29 | It is understood that obfuscation does not make it impossible 30 | to recover the original source code, only that is is harder 31 | and that steps have been taken to avoid obvious disclosure. 32 | 33 | ## Recommendation Components 34 | 35 | N/A 36 | ## Guidance 37 | 38 | Before employing obfuscation, validate that the value provided 39 | by obfuscation warrants the effort and downsides. Including 40 | license headers in the code may be an alternative in some cases. 41 | If the product is based on an open source upstream, the code is already 42 | available publicly and therefore many of the motivations listed above 43 | will not apply. Typically obfuscation is not used within Red Hat 44 | as products are based on freely available open source. 45 | 46 | Minification is a related practice to obfuscation in that it 47 | makes source code less readable with the motivation of reducing 48 | the number of bytes that must be transferred to a clients browser. 49 | It is widely used for front-end JavaScript. 50 | 51 | In the team's experience the use of existing minification tools 52 | are often enough to meet an organization's requirement for obfuscation. 53 | These tools are broadly used, and therefore add little risk of 54 | functional or performance issues being introduced. Our teams have 55 | had success using [Terser](https://www.npmjs.com/package/terser) and 56 | [esbuild](https://esbuild.github.io/). 57 | 58 | If you are going to both minify and use a separate obfuscator, 59 | minify first. 60 | 61 | Expect a performance degradation if you use an obfuscator as 62 | opposed to one of the minification tools. For example 63 | [javascript-obfuscator](https://www.npmjs.com/package/javascript-obfuscator) 64 | indicates you can expect your code to be 15-80% slower. 65 | 66 | For those cases where minification tools are not sufficient one of 67 | our teams has used [bytenode](https://github.com/bytenode/bytenode) 68 | succesfully. 69 | 70 | ### Source maps 71 | 72 | One of the downsides of using obfuscation is that it makes 73 | debugging more difficult. minification tools typically support 74 | the generation of 75 | [source maps](https://en.wikipedia.org/wiki/Minification_(programming)#Source_mapping) 76 | which can help map back to the original source code. Making 77 | source maps available would at least partially invalidate 78 | the benefits of obfuscation so when obfuscation is a requirement they 79 | should not be made publicly available. 80 | 81 | Source maps should still be generated and stored with the original 82 | source code for each release. For front-end JavaScript teams should validate 83 | the process of using offline source maps in their typical problem 84 | investigation workflow. This 85 | [article](https://dev.to/ivanstanevich/using-js-source-maps-in-production-1ecc) 86 | has some suggestions for doing that. 87 | 88 | For back end JavaScript it should be possible to use the source maps 89 | to get a readable stack trace from a minified version provided by a 90 | customer. There are packages to do this like [stacktracey](https://github.com/xpl/stacktracey), 91 | however, the team does not have direct experience doing this yet to report on 92 | how easy that is to do. 93 | 94 | 95 | -------------------------------------------------------------------------------- /docs/development/serverless.md: -------------------------------------------------------------------------------- 1 | # Serverless 2 | 3 | Serverless is a powerful and popular development model where you don’t have to worry about managing and maintaining your application infrastructure. There are two main paradigms when it comes to Serverless. The first is the operations paradigm which is responsible for the orchestration of containers, scaling them up from and down to zero running instances. 4 | 5 | The second paradigm is the functions programming model. In the serverless context, a function is a single-purpose piece of code created by the developer but run and monitored by the managed infrastructure. A serverless function’s value is its simplicity and swiftness, which can entice even those who don’t consider themselves developers. 6 | 7 | 8 | ## Recommended Components 9 | 10 | N/A 11 | 12 | ## Guidance 13 | 14 | While the team doesn't have to much experience in the serverless realm at the moment, there is still some guidance that can be recommended. 15 | 16 | ### Functions 17 | 18 | One of the main recommendations that we can give related to Functions and Serverless in general, is to keep things as stateless as possible. When a request comes in, the function will scale up and become available for a set period of time before it scales back down and the current context is destroyed. 19 | 20 | Node.js is one of the top recommended languages for Functions due to Node's small memory foot print, quick startup time and asynchronous nature. 21 | 22 | #### Challenges 23 | 24 | There are some challenges when deciding to use functions. The first is that there is no standard. How a function should be created and what data and types are available in the function signature, is based on the vendor that the function is being created for. While not a standard for how functions should be created, the [CloudEvents specification](https://github.com/cloudevents/spec) standardizes on many platforms, such as Knative Serverless and Google Cloud Functions, the payload that is sent. 25 | 26 | Second is the local development and remote debugging experience. This can be challenging for a couple of reasons. First, when developing locally, if the function needs to interact with other remote services, this can be challenging to setup. Second, once the function is running on its respective serverless platform, debugging the remote function can be challenging, since it is no small feat to connect a debugger to a remote service. 27 | 28 | There are tools that exist to help with this experience, such as the [faas-js-runtime](https://www.npmjs.com/package/faas-js-runtime), but again, this is based on a specific vendor. 29 | 30 | ### Serverless Platforms 31 | 32 | #### Openshift Serverless 33 | 34 | OpenShift Serverless is based on the open source Knative project, which provides portability and consistency across hybrid and multi-cloud environments by enabling an enterprise-grade serverless platform. 35 | 36 | Developers on OpenShift Serverless can use the provided Kubernetes native APIs, as well as familiar languages and frameworks, to deploy applications and container workloads. 37 | 38 | OpenShift Serverless on OpenShift Container Platform enables stateless serverless workloads to all run on a single multi-cloud container platform with automated operations. Developers can use a single platform for hosting their microservices, legacy, and serverless applications. 39 | 40 | 62 | 63 | ## Further Reading 64 | 65 | [Node.js Circuit Breakers for Serverless Functions](https://developers.redhat.com/articles/2021/09/15/nodejs-circuit-breakers-serverless-functions) 66 | 67 | [Create your first serverless function with Red Hat OpenShift Serverless Functions](https://developers.redhat.com/blog/2021/01/04/create-your-first-serverless-function-with-red-hat-openshift-serverless-functions#) 68 | 69 | [Node.js serverless functions on Red Hat OpenShift, Part 1: Logging](https://developers.redhat.com/articles/2021/07/01/nodejs-serverless-functions-red-hat-openshift-part-1-logging) 70 | 71 | [Node.js serverless functions on Red Hat OpenShift, Part 2: Debugging locally](https://developers.redhat.com/articles/2021/07/13/nodejs-serverless-functions-red-hat-openshift-part-2-debugging-locally) 72 | 73 | [Node.js serverless functions on Red Hat OpenShift, Part 3: Debugging on a cluster](https://developers.redhat.com/articles/2021/12/08/nodejs-serverless-functions-red-hat-openshift-part-3-debugging-cluster) 74 | 75 | -------------------------------------------------------------------------------- /docs/development/testing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Testing 6 | 7 | ## Recommended Packages 8 | 9 | The best package to use for testing often depends on the type and scope of a project 10 | versus one size fits all. For that reason we'll mention two of the test frameworks 11 | that the team has had success with. 12 | 13 | ## Jest - 14 | 15 | [jest][] is a popular testing framework from Facebook. It excels at testing React and other 16 | component-based web applications, and can be used in other contexts. It is considered an 17 | _opinionated_ framework, as it provides its own set of assertions, spies/stubs/mocks, and 18 | other features (such as snapshot testing and code coverage) out-of-the-box. 19 | 20 | Jest is now an [OpenJS Foundation project](https://openjsf.org/blog/2022/05/11/openjs-foundation-welcomes-jest/) 21 | 22 | ## Mocha - 23 | 24 | [mocha][] is a widely used, mature (created in 2011) and stable project. While Node.js 25 | is the main area of focus and support, Mocha can also be used in a browser context. 26 | Mocha is an _unopinionated_ framework with a large ecosystem of plugins and extensions. 27 | 28 | Mocha is an [OpenJS Foundation][] project with open governance. 29 | 30 | ## Guidance 31 | 32 | Both Mocha and Jest provide test parallelization. By default this is disabled in Mocha, 33 | as many use-cases see a negative performance impact when running tests in parallel. If you 34 | experience longer test times than expected you should check if enabling or disabling 35 | parallelism will improve test run times. 36 | 37 | ### When Jest might be the better choice 38 | 39 | When testing React or component-based applications. 40 | 41 | When using a compile-to-JavaScript language (like TypeScript). 42 | 43 | When snapshots are useful. [Snapshots][] provide an easy to use way of testing output 44 | of a function and saving the result as a snapshot artifact, which can then be used to 45 | compare against as a test. As an example: 46 | 47 | ```shell 48 | test('unknown service', () => { 49 | expect(() => { 50 | bindings.getBinding('DOEST_NOT_EXIST'); 51 | }).toThrowErrorMatchingSnapshot('unknown service'); 52 | }); 53 | ``` 54 | 55 | The first time the test is run it will create/store a snapshot of the expected exception. 56 | On subsequent runs if the exception does not match the snapshot, it will report 57 | a test failure. This makes generating/capturing the result from an operation being tested 58 | fast and easy. 59 | 60 | ### When Mocha might be the better choice 61 | 62 | When you want a smaller dependency tree (91 packages versus 522). 63 | 64 | When Jest's opinions, environment proxies and dependency upon [babel][] are unfavorable for your use-case. 65 | 66 | As an example of potential problems with Jest's environment proxies, Jest replaces globals in the environment in a 67 | way that can cause failures with native addons. As an example, this simple test fails: 68 | 69 | ```JavaScript 70 | const addon = require('bindings')('hello'); 71 | 72 | describe('test suite 1', () => { 73 | test('exception', () => { 74 | expect(addon.exception()).toThrow(TypeError); 75 | }); 76 | }); 77 | ``` 78 | 79 | even thought the addon is throwing the expected exception: 80 | 81 | ```C++ 82 | static napi_value ExceptionMethod(napi_env env, napi_callback_info info) { 83 | napi_throw_type_error(env, "code1", "type exception"); 84 | return NULL; 85 | } 86 | ``` 87 | 88 | and the failure reports the exception as `TypeError: type exception` 89 | 90 | ```shell 91 | FAIL __tests__/test.js 92 | ● test suite 1 › exception 93 | 94 | TypeError: type exception 95 | 96 | 3 | describe('test suite 1', () => { 97 | 4 | test('exception', () => { 98 | > 5 | expect(addon.exception()).toThrow(TypeError); 99 | | ^ 100 | 6 | }); 101 | 7 | }); 102 | 8 | 103 | 104 | at Object. (__tests__/test.js:5:18) 105 | ``` 106 | 107 | An equivalent test runs successfully with Mocha. The full source for the test is here: https://github.com/nodeshift-blog-examples/jest-with-native-addon-issue 108 | 109 | ### Recommended Packages to Use Alongside Mocha 110 | 111 | Because Mocha is unopinionated, it does not ship with "batteries included." While Mocha is usable 112 | without any other third-party library, many users find the following libraries and tools helpful. 113 | 114 | _See the [mocha documentation][] and [examples repository][] for more information on integrating with other tools_. 115 | 116 | #### Assertion Library 117 | 118 | Most Mocha users will want to consume a third-party _assertion library_. Besides the Node.js 119 | built-in [`assert` module][], Mocha recommends one of the following: 120 | 121 | - [chai][]: the most popular general-purpose assertion library, with traditional and "natural language" APIs available 122 | - [unexpected][]: a string-based natural language API, Mocha uses Unexpected in its own tests 123 | 124 | Both of the above have their own plugin ecosystems. 125 | 126 | #### Stubs, Spies and Mocks 127 | 128 | Many users will want a library providing _stubs, spies and mocks_ to aid isolation when writing unit tests. 129 | 130 | - [sinon][]: the most popular stub, spy and mock library; mature 131 | - [testdouble][]: a full-featured library with the ability to mock at the module level 132 | 133 | Both of the above have their own plugin ecosystems. 134 | 135 | #### Code Coverage 136 | 137 | Mocha does not automatically compute code coverage. If you need it, use: 138 | 139 | - [nyc][]: the most popular code-coverage tool; the successor CLI for Istanbul 140 | 141 | For more on Code Coverage, see the [Code Coverage](./code-coverage) section 142 | 143 | [`assert` module]: https://nodejs.org/api/assert.html#assert_assert 144 | [babel]: https://babeljs.io 145 | [chai]: https://www.npmjs.com/package/chai 146 | [examples repository]: https://github.com/mochajs/mocha-examples 147 | [jest]: https://www.npmjs.com/package/jest 148 | [karma]: https://www.npmjs.com/package/karma 149 | [mocha documentation]: https://mochajs.org 150 | [mocha]: https://www.npmjs.com/package/mocha 151 | [nyc]: https://www.npmjs.com/package/nyc 152 | [openjs foundation]: https://openjsf.org 153 | [protractor]: https://www.npmjs.com/package/protractor 154 | [sinon]: https://www.npmjs.com/package/sinon 155 | [testdouble]: https://www.npmjs.com/package/testdouble 156 | [unexpected]: https://www.npmjs.com/package/unexpected 157 | [webdriverio]: https://www.npmjs.org/package/webdriverio 158 | [snapshots]: https://jestjs.io/docs/snapshot-testing 159 | 160 | ## Further Reading 161 | 162 | * [Introduction to the Node.js reference architecture: Testing](https://developers.redhat.com/articles/2023/07/27/introduction-nodejs-reference-architecture-testing) 163 | -------------------------------------------------------------------------------- /docs/development/typescript.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | # Typescript 5 | 6 | TypeScript is a language that compiles to JavaScript and provides static typing by extending the JavaScript syntax. It is worth considering for larger projects as it can bring the following benefits: 7 | 8 | - **Error detection**: certain classes of errors can be caught at compile time rather than causing a runtime error, e.g. reading a property from an object that may be undefined. 9 | 10 | - **Contextual help in code editors**: for supported editors, TypeScript enables rich code completion both for project code and imported modules via the [DefinitelyTyped](https://definitelytyped.org/) project. 11 | 12 | - **Refactoring support**: changing the signature of a function or structure of an object in an incompatible way will cause compilation errors where it is used. TypeScript also enables automated refactorings such as renaming variables across multiple files and extracting methods. 13 | 14 | TypeScript does _not_ provide any runtime type checking. To validate data at runtime, use a library such as [ajv](https://github.com/ajv-validator/ajv) in combination with TypeScript. 15 | 16 | ## Transpilers 17 | 18 | Node.js does not support running TypeScript natively, so it must first be transpiled to JavaScript. We recommend the `tsc` transpiler that is shipped with [typescript](https://www.npmjs.com/package/typescript). This supports both type checking and transpilation to JavaScript. 19 | 20 | For front end development, sometimes [`babel`](https://babeljs.io) is used with the [`@babel/preset-typescript`](https://babeljs.io/docs/en/babel-preset-typescript) preset for transpilation, but this does _not_ support type checking and we do not recommend it for Node.js. More information on choosing a transpiler can be found in the [typescript documentation](https://www.typescriptlang.org/docs/handbook/babel-with-typescript.html). 21 | 22 | Avoid mixing transpilers on the same project as this can lead to inconsistencies. Sometimes projects unintentionally use `babel` for their jest tests as it is the [default](https://jestjs.io/docs/getting-started#using-typescript). 23 | 24 | ## Transpiling in development 25 | 26 | The `tsc` compiler provides a useful watch mode, activated by the `-w` or `--watch` flag. This will automatically re-transpile source files when they change. If you want to also restart a Node.js server process when this happens, you can use this in combination with [nodemon](https://nodemon.io) using a module such as [concurrently](https://www.npmjs.com/package/concurrently). An example script for `package.json`: 27 | 28 | ```json 29 | { 30 | "scripts": { 31 | "dev": "concurrently -n tsc,node 'tsc -w' 'nodemon -w dist dist/server.js'" 32 | } 33 | } 34 | 35 | ``` 36 | 37 | If you're using `babel` which does not perform type checking, it is a good idea to run `tsc --noEmit` periodically to check the entire codebase, e.g. as a git pre-push hook. 38 | 39 | ## Ship JavaScript not TypeScript for deployment 40 | 41 | It's best practice to run the transpilation step as part of your deployment pipeline rather than dynamically in production, for the follow reasons: 42 | 43 | 1. Type errors will get caught before code is deployed 44 | 1. The application will start up more quickly as there is no need to transpile 45 | 1. You can ship a smaller container as it doesn't need to include the transpiler 46 | 47 | ## Recommended configuration 48 | 49 | The typescript community have produced a series of [recommended base configurations for various versions of node](https://github.com/tsconfig/bases/). Using an up to date version means typescript will not polyfill capabilities that are natively supported by node, which can improve runtime performance. 50 | 51 | In addition to the above, we recommend setting the following in the `compilerOptions` section of the `tsconfig.json` file: 52 | 53 | ```json 54 | "isolatedModules": true 55 | ``` 56 | 57 | This flag enables compatibility with Babel and other transpilers that process a project a single file at a time. Some TypeScript features such as `const enums` are not compatible with isolated modules, see the [TypeScript documentation](https://www.typescriptlang.org/tsconfig#isolatedModules) for more details. Turning on this flag will produce warnings if those features are used. 58 | 59 | ```json 60 | "strict": true 61 | ``` 62 | 63 | Strict mode turns on a [number of other flags](https://www.typescriptlang.org/tsconfig#strict) which can help prevent bugs in your code. If you're migrating an existing project to typescript it might be difficult to turn this on, but for new projects it is recommended. 64 | 65 | ```json 66 | "esModuleInterop": true 67 | ``` 68 | 69 | This improves TypeScript's [interoperability with with CommonJS/AMD/UMD modules](https://www.typescriptlang.org/tsconfig#esModuleInterop), particularly with regard to how default imports are handled. It is automatically enabled in the Node.js base configurations (see above). 70 | 71 | ## Hierarchical TypeScript Configuration 72 | 73 | If you want to maintain consistency across several components (e.g. microservices) it is a good idea to create a standard base configuration which specifies appropriate and then have every component inherit from it. This can be done by publishing the base configuration as a versioned npm module and then referencing it in a `tsconfig.json` file as follows: 74 | 75 | ```json 76 | "extends": "@yourproject/projectbase/tsconfig.json" 77 | ``` 78 | 79 | Multiple levels of inheritance are possible, so the `projectbase` configuration could inherit from one of the recommended base configurations described above. 80 | 81 | ## Sharing types with npm modules 82 | 83 | If you are publishing a library code rather than an application it is good practice to publish types for that module alongside the compiled code. There are 2 steps required to enable this: 84 | 85 | 1. Turn on [declaration generation](https://www.typescriptlang.org/tsconfig#declaration) in your `tsconfig.json`: 86 | 87 | ```json 88 | { 89 | "compilerOptions": { 90 | "declaration": true 91 | } 92 | } 93 | ``` 94 | 2. Reference the main declaration file in your `package.json`: 95 | 96 | ```json 97 | { 98 | "types": "./lib/index.d.ts" 99 | } 100 | ``` 101 | You should also ensure you include dependencies for the types of modules that you depend on, see the [TypeScript documentation](https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html) for further details. 102 | 103 | ## Further Reading 104 | 105 | [Introduction to the Node.js reference architecture: Typescript](https://developers.redhat.com/articles/2022/04/11/introduction-nodejs-reference-architecture-part-8-typescript) 106 | -------------------------------------------------------------------------------- /docs/functional-components/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Functional components", 3 | "position": 3 4 | } 5 | -------------------------------------------------------------------------------- /docs/functional-components/auth.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Authentication 6 | 7 | ## Recommended Components 8 | 9 | - Passport - http://www.passportjs.org/ 10 | Passport is authentication middleware for Node.js. Extremely flexible and modular, Passport can be unobtrusively dropped in to any Express-based web application. Is based on strategies which allows for a large number of integrations. 11 | 12 | - IBM Cloud AppID https://cloud.ibm.com/docs/services/appid 13 | App ID helps developers to easily add authentication to their web and mobile apps with few lines of code, and secure their Cloud-native applications and services on IBM Cloud. 14 | 15 | - Istio - https://istio.io/ 16 | Istio provides a service mesh, includes security features https://istio.io/docs/tasks/security/ 17 | IBM provides an Istio Adapter for App Identity and Access https://istio.io/docs/reference/config/policy-and-telemetry/adapters/app-identity-access-adapter/ 18 | 19 | ## Guidance 20 | 21 | - Use Helmet to configure http headers to address security attacks. 22 | 23 | - Use Passport to handle your web strategy 24 | 25 | - Use a web strategy based on AppID whenever possible. 26 | 27 | - There is a difference between a WebApp/BFF(Backend for Frontend) and a pure Backend API that never deals with a Frontend like a Web Browser. Knowning this difference will help you understand the requirements in terms of security. 28 | 29 | - A Frontend WebApp should never handle end user credentials such as username/password, it should always delegate to an Authorization Server for example AppID service. https://github.com/ibm-cloud-security/appid-video-tutorials/blob/master/02a-simple-node-web-app/app.js 30 | 31 | - A pure Backend API that never deals with a Frontend should never be concern of redirecting or dealing with end users, they would require an access/AOI token or assume the proxy/gateway in front is already handling this and not require token at all. https://github.com/ibm-cloud-security/appid-video-tutorials/blob/master/02b-simple-node-backend-app/app.js 32 | 33 | - The browser/client should never have access to access token. 34 | 35 | - The Authorization Server will interact with the user and once is authenticated it will return to the browser with a grant code, which in turn can be used by the Web App request an access token. With this access token the WebApp can access a Backend API for a resource. 36 | 37 | - Use the refresh token whenever possible, this avoids re-authentication. 38 | 39 | - Do not use OAUTH2 implicit grant (https://tools.ietf.org/html/rfc6749#section-4.2), instead use the Authorization code workflow (https://tools.ietf.org/html/rfc6749#section-4.1) whenever possible. 40 | 41 | - Use OIDC ID token for authentication, they are represented as JSON Web Token (JWT) and it contains the requested claims. 42 | 43 | - When using Istio: 44 | 45 | - Istio Adapter for AppID can handle the authentication and authorization of the client, this leaves the nodejs service without the responsibilities of handling authentication or authorization. https://github.com/ibm-cloud-security/app-identity-and-access-adapter 46 | 47 | - Using Istio you can handle authorization based on roles for the nodejs service, for example all authenticated users can read data via http method GET, but only users with `role=admin` are allowed to write data via http method POST. 48 | 49 | ## Learning Resources 50 | 51 | - [Technologies Under the Hood (OAuth2, OIDC, JWT, Bearer Token)](https://www.youtube.com/watch?v=ndlk-ZhKGXM&list=PLbAYXkuqwrX2WLQqR0LUtjT77d4hisvfK&index=2) 52 | 53 | - [Protecting Node.js Web Applications with IBM Cloud App ID](https://www.youtube.com/watch?v=6roa1ZOvwtw&list=PLbAYXkuqwrX2WLQqR0LUtjT77d4hisvfK&index=3) 54 | 55 | - [Protecting Node.js Backend Application with IBM Cloud App ID](https://www.youtube.com/watch?v=jJLSgkHpZwA&list=PLbAYXkuqwrX2WLQqR0LUtjT77d4hisvfK&index=4) 56 | -------------------------------------------------------------------------------- /docs/functional-components/consuming-services.md: -------------------------------------------------------------------------------- 1 | # Consuming Services 2 | 3 | Consuming services over HTTPs is a common pattern in Node.js applications. 4 | Most often these are [REST](https://www.ibm.com/cloud/learn/rest-apis) 5 | apis. 6 | 7 | Node.js has a built in HTTP/HTTPs client, however, the experience of the 8 | team is that real deployments need more capabilities than provided by that 9 | built in client. 10 | 11 | This section is the compliment to 12 | [REST APIs Development](./rest-api-development.md) sharing our experience 13 | with the packages used to comsumes services instead of building 14 | them. 15 | 16 | ## Recommended Packages 17 | 18 | Two packages that the team has had success with are: 19 | 20 | - [axios](https://www.npmjs.com/package/axios) is a promise based 21 | HTTP client for the browser and node.js. 22 | Axios is a client that is full featured and has 23 | significant ecosystem usage. 24 | 25 | - [node-fetch](https://github.com/node-fetch/node-fetch) is a light-weight module that brings 26 | [window.fetch](https://fetch.spec.whatwg.org/) to Node.js. 27 | Using the fetch API provides fewer features, however it has the 28 | advantage of being almost what is provided in the browser. While node-fetch version 3 is 29 | ESM only, the project has indicated that they 30 | [continue to maintain version 2](https://github.com/node-fetch/node-fetch#commonjs). Node.js has an 31 | [experimental version of fetch](https://nodejs.org/docs/latest/api/globals.html#fetch) 32 | which may be a good alternate choice in the future. 33 | 34 | ## General Guidance 35 | 36 | Plan to use a more complete HTTP client from the start of your development. 37 | The experience of the team is that real deployments need more capabilities 38 | than provided by the Node.js HTTP client. Some of the areas where team 39 | commonly find additional functionality is required include: 40 | 41 | * Automatic Retries limited to a specified time period 42 | * Caching based on response cache headers to reduce pulling same content repeatedly 43 | * Error handling based on error code to retry or fail quickly 44 | 45 | If both the front and backend are written in JavaScript, using the same library 46 | across both front end and backend is good practice. This may favor node-fetch 47 | as it avoids having to pull in an additional library in the browser. 48 | 49 | The tools outlined in [REST APIs Development](./rest-api-development.md) may 50 | generate clients in addition to stubs for the API itself. If those 51 | tools generate clients for you, feel comfortable using the http packages 52 | they depend on even if they are not those recommended above. 53 | 54 | Many cloud SDKS provide a higher level API and should be preferred 55 | versus using the HTTP clients recommended above even if they use 56 | a different HTTP client under the covers. 57 | 58 | When using node-fetch all HTTP codes are treated as successful, even the 4XX and 59 | 5XX. In order to get the behaviour expected with most other clients you will 60 | need to add something like 61 | 62 | ```JavaScript 63 | if (res.ok) {return res.json()} else {throw new Error(...) } 64 | ``` 65 | The fetch API was designed for the browser and cannot be fully 66 | implemented in the back end. In addition, it does cover all aspects 67 | required for a back-end implementation. The API 68 | provided by [node-fetch](https://github.com/node-fetch/node-fetch) 69 | and the 70 | [experimental version of fetch](https://nodejs.org/docs/latest/api/globals.html#fetch) 71 | in Node.js are not the same as difference choices were made on how 72 | to handle the gaps. For this reason moving from 73 | node-fetch to the built in version of fetch in Node.js will not be seamless. 74 | 75 | While [request](https://www.npmjs.com/package/request) is a widely used 76 | package, it has been deprecated and will not be getting updates. 77 | For new applications we recommend you 78 | do not use it and start with one of the above. (TODO I remember 79 | a mentioned of a maintained fork of request and that it 80 | would be useful to mention here). 81 | -------------------------------------------------------------------------------- /docs/functional-components/data-caching.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Data Caching 6 | 7 | There are two main types of caching used within Node.js applications. These include: 8 | 9 | - in-process 10 | - cluster wide 11 | 12 | ## Recommended packages 13 | 14 | | Caching type | Recommended client | 15 | | ------------ | ------------------ | 16 | | in process | [lru-cache][] | 17 | | cluster wide | [ioredis][] | 18 | 19 | ### In process 20 | 21 | Recommendation is to use [lru-cache][] which is broadly used within the 22 | the `teams` organizations and in the JavaScript ecosystem with > 28 million weekly 23 | downloads. 24 | 25 | ### Cluster wide 26 | 27 | For cluster wide caching with Redis, the recommendation is to use [ioredis][]. 28 | There are 2 good options with no clear technical winner for redis, but the `teams` 29 | organizations have experience in production with [ioredis][] so 30 | that is why it is recommended over [redis][]. Depending on the server you are 31 | using there may be features which are only available in a server specific client and 32 | if you need those features then using the specific client makes sense insteda of ioredis. 33 | 34 | ## Guidance 35 | 36 | - Consider your call behaviour to ensure you need to cache a specific piece of data at all 37 | - For cluster wide caching, include a version prefix as part of keys from the start, otherwise you 38 | will encouter problems when you try to update the caching schema 39 | 40 | [ioredis]: https://www.npmjs.com/package/ioredis 41 | [lru-cache]: https://www.npmjs.com/package/lru-cache 42 | [redis]: https://www.npmjs.com/package/redis 43 | -------------------------------------------------------------------------------- /docs/functional-components/databases.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Databases 6 | 7 | We'll not recommend which database to use but instead share 8 | our experience with the Node.js clients used to connect 9 | to whichever database your project/organization has chosen. 10 | 11 | In most cases there is only a single client with widespread 12 | usage, often provided by the project or organizations which 13 | builds the database itself. 14 | 15 | ## Recommended packages 16 | 17 | Members of the team have had success using the following 18 | clients: 19 | 20 | | Server | Recommended client | 21 | | ------------- | -------------------------- | 22 | | Cloudant | [@ibm-cloud/cloudant][] | 23 | | CouchDB | [nano][] | 24 | | Elasticsearch | [@elastic/elasticsearch][] | 25 | | Generic SQL | [odbc][] | 26 | | IBM Db2 | [ibm_db][], [odbc][] | 27 | | Mongo | [mongodb][] | 28 | | Postgress | [pg][] | 29 | | Redis | [ioredis][] | 30 | 31 | There are popular databases for which there are 32 | no recommendations. However, if the team did not 33 | have some experience with the Node.js client we've not 34 | included it in the list. 35 | 36 | ### General Guidance 37 | 38 | - Many clients support connection pooling. When available use 39 | pooling to avoid creating a new connection for each request. 40 | 41 | - By default many clients will return all results for a query 42 | unless you take steps to limit the result size. Unless you are 43 | sure the result set will always be a manageable size use 44 | avaliable options to return only a subset of results at a time. 45 | 46 | - Some of the the clients require a native database binding 47 | to be installed. This may limit the platforms on which 48 | you can run the client. Some may also support both 49 | pure JavaScript and native bindings. In those cases 50 | pure JavaScript will be easier to install but the 51 | native binding may provide better performance. 52 | 53 | ## Postgress 54 | 55 | Recommendation is to use [pg][] as the most 56 | widely used (if not only) client. 57 | 58 | ## Mongo 59 | 60 | Recommendation is to use [mongodb][] which is the 61 | official MongoDB driver provided by the Mongo 62 | project. 63 | 64 | ## Redis 65 | 66 | Recommendation is to use [ioredis][]. 67 | There are 2 good options with no clear technical winner, but IBM has experience 68 | in production with [ioredis][] so that is why it is recommended over [redis][]. 69 | 70 | ### Guidance 71 | 72 | If you are already using redis for messaging this can provide a low cost option 73 | but does not support more advanced features like High Availability. 74 | 75 | ## Cloudant 76 | 77 | Current versions of cloundant require a cloudant specific client 78 | which is [cloudant-node-sdk][]. While it is version 0.0.16 as when 79 | this section was last updated, it is a fork of the [nano][] CouchDB 80 | client which has a long history. This client can also be used 81 | to access CouchDB instances if you are using both Cloudant and 82 | CouchDB. 83 | 84 | If you are using classic Cloudant instances then you can use the clients 85 | recommended for CouchDB 86 | 87 | ## IBM Db2 88 | 89 | On databases except for Db2 for i the recommendation is to 90 | use [ibm_db][] which is the official driver provided by IBM. 91 | 92 | For the Db2 for i database the primary recommendation is to 93 | use [odbc][] which is maintained by IBM and allows you to 94 | do local development and then deploy your application 95 | to the IBM i platform. If you are doing both development and 96 | depolyment on IBM i then using [idb-connector][], [idb-pconnector][] 97 | are good alternatives which require no configuration 98 | or additional installation. 99 | 100 | ### Guidance 101 | 102 | - On IBM i clients can inherit authentication based on the Operating 103 | system user. In these cases ensure you run the Node.js program 104 | using the client as non-admin user. 105 | 106 | ## Elasticsearch 107 | 108 | Recommendation is to use [@elastic/elasticsearch][] which is the 109 | official driver provided by Elastic. Note that this client is replacing 110 | the original client provided by Elastic which is being deprecated. 111 | 112 | ## CouchDB 113 | 114 | The primary recommendation is to use [nano][] which 115 | is the official Apache CouchDB client. 116 | 117 | A secondary recommendation is [pouchdb][] which makes it easy to 118 | have a local copy which is kept in sync and is great for unit testing. 119 | 120 | ## Generic SQL 121 | 122 | If there is no database specific client or you want your code to be database 123 | agnostic the [odbc][] client is a good choice. It's currently maintained by 124 | IBM team and is the recommended client for access to the IBM i database. 125 | 126 | This client should work for any database for which there is an 127 | [odbc](https://github.com/microsoft/ODBC-Specification/blob/master/ODBC%204.0.md) 128 | compliant driver. 129 | 130 | ### Guidance 131 | 132 | Use the built in odbc connection pooling support to avoid creating/destroying 133 | a connecttion for each request. 134 | 135 | Use the odbc built in functions for: 136 | 137 | - isolation/commit 138 | - transaction support 139 | 140 | instead of the SQL equivalents. 141 | 142 | [ioredis]: https://www.npmjs.com/package/ioredis 143 | [redis]: https://www.npmjs.com/package/redis 144 | [pg]: https://www.npmjs.com/package/pg 145 | [mongodb]: https://www.npmjs.com/package/mongodb 146 | [oracledb]: https://www.npmjs.com/package/oracledb 147 | [mysql]: https://www.npmjs.com/package/mysql 148 | [mysql2]: https://www.npmjs.com/package/mysql2 149 | [@elastic/elasticsearch]: https://www.npmjs.com/package/@elastic/elasticsearch 150 | [odbc]: https://www.npmjs.com/package/odbc 151 | [cassandra-driver]: https://www.npmjs.com/package/cassandra-driver 152 | [idb-connector]: https://www.npmjs.com/package/idb-connector 153 | [idb-pconnector]: https://www.npmjs.com/package/idb-pconnector 154 | [ibm_db]: https://www.npmjs.com/package/ibm_db 155 | [mssql]: https://npmjs.com/package/mssql 156 | [@ibm-cloud/cloudant]: https://www.npm.js.com/package/@ibm-cloud/cloudant 157 | [nano]: https://www.npmjs.com/package/nano 158 | [pouchdb]: https://www.npmjs.com/package/pouchdb 159 | -------------------------------------------------------------------------------- /docs/functional-components/graphql.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # GraphQL Development 6 | 7 | GraphQL developement requires number of tools and packages that can be used on both client and server. 8 | Our target will be to provide comprehensive set of the tools to add graphql support for both client and server side applications 9 | 10 | ## Recommended Packages for Node.js Server development 11 | 12 | - `express-graphql` - https://graphql.org/graphql-js/express-graphql 13 | Exposes GraphQL schema using Express.js 14 | 15 | - `GraphQL Tools` - https://github.com/ardatan/graphql-tools 16 | Builds GraphQL schema using resolvers 17 | 18 | - `DataLoader` - https://github.com/graphql/dataloader 19 | Prevents from overfetching data when querying relationships 20 | 21 | ## Recomended packages for Client side development 22 | 23 | - `GraphQL-Tag` - https://github.com/apollographql/graphql-tag 24 | Compiles graphql schema on the client (provides browserify plugin) 25 | 26 | - `URQL` - https://formidable.com/open-source/urql 27 | GraphQL Client with caching and offline support 28 | 29 | - `Apollo-Client` - https://github.com/apollographql/apollo-client/ 30 | Alternative GraphQL Client with caching and offline support 31 | 32 | - `GraphQL-Code-Generator` - https://graphql-code-generator.com 33 | Generates TypeScript source code for client and server 34 | 35 | ## Recommended Tools for visualizing GraphQL Schema and Queries 36 | 37 | - `graphiql` - https://github.com/graphql/graphiql 38 | Graphiql is web application that allows you to build and execute GraphQL queries against your schema 39 | 40 | - `GraphQL-CLI` https://github.com/Urigo/graphql-cli 41 | Suite of tools and commands for performing various operations on GraphQL schema. 42 | 43 | ## Recomended practices for GraphQL Schema development 44 | 45 | - `GraphQL Rules` - https://graphql-rules.com/ 46 | Set of recomendations for building proper schema 47 | 48 | - `GraphQL CRUD` - https://graphqlcrud.org 49 | Set of rules and generators to automate building GraphQL schema 50 | 51 | ## Guidance 52 | 53 | When building GraphQL API from scratch we recomend using reference GraphQL-js reference implementation which was 54 | proven to be the most performant and have continous support from community. Entire development is currently backed by Linux foundation. 55 | 56 | ### GraphQL Server 57 | 58 | For GraphQL Server we recomend using GraphQL-Express for exposing GraphQL APIs over the network and GraphQL-Tools to build GraphQL Schema: 59 | 60 | https://github.com/ardatan/graphql-tools#example 61 | 62 | Developers can use top level database query languages. 63 | We recomend using Knex(http://knexjs.org/) for performing queries from GraphQL to relational databases. 64 | 65 | If your GraphQL Schema contains relationships that can lead to "N+1 Problem", please consider using DataLoader library. 66 | 67 | https://github.com/graphql/dataloader 68 | 69 | Usage of the dataloader will be specific to your database/ORM solution. 70 | 71 | ### GraphQL Client 72 | 73 | For GraphQL client we recomend URQL that can work with React and any other JavaScript based library. 74 | 75 | https://formidable.com/open-source/urql 76 | 77 | When using module bundler we strongly recomend to compile your graphql queries using GraphQL-Tag: 78 | 79 | https://github.com/apollographql/graphql-tag 80 | 81 | ### Typescript support 82 | 83 | If you use typescript in your project we recomend GraphQL-Code-Generator to generate typings for both client and server: 84 | 85 | https://graphql-code-generator.com 86 | 87 | ### Instrumentation and Tracking 88 | 89 | For instrumentation and tracking we recomend using official OpenTelemetry package 90 | 91 | https://www.npmjs.com/package/@opentelemetry/instrumentation-graphql 92 | 93 | ## Rate Limiting and Query Complexity 94 | 95 | When building GraphQL API we often need to restrict it in terms of complexity and query rate. 96 | 97 | For rejecting complex queries and detecting possible API missuse we recomend using 98 | 99 | https://github.com/slicknode/graphql-query-complexity 100 | 101 | For building fixed window rate limiting middleware for GraphQL we recomend 102 | 103 | https://github.com/ravangen/graphql-rate-limit 104 | 105 | ## Authorization 106 | 107 | When building GraphQL we can build our authorization logic inside resolvers. 108 | Developers can use any library or solution that is specific to their infrastructure. 109 | We recomend to follow official authorization guide: 110 | 111 | https://graphql.org/learn/authorization 112 | 113 | For `Keycloak SSO` users we recomend library that provides helpers and GraphQL directives for authorization and authentication: 114 | 115 | https://github.com/aerogear/keycloak-connect-graphql 116 | 117 | ### Persisted queries 118 | 119 | Persisted queries are mechanism to improve performance by utilizing already cached and well known queries. 120 | Those queries can be also later hosted on the CDN. 121 | 122 | For persisted queries we can use approaches that are: 123 | 124 | - Dynamic (no need to compile queries on client as server caches them) 125 | - Static (requires client side compilation) 126 | 127 | For static persited queries we recomend 128 | https://github.com/valu-digital/graphql-codegen-persisted-query-ids 129 | 130 | For dynamic persisted queries we recomend 131 | 132 | 2. [Apollo APQs](https://www.apollographql.com/docs/apollo-server/performance/apq/) which needs [Apollo server](https://www.apollographql.com/docs/apollo-server/) 133 | 134 | ## Further Reading 135 | 136 | [Introduction to the Node.js reference architecture: GraphQL](https://developers.redhat.com/articles/2021/06/22/introduction-nodejs-reference-architecture-part-4-graphql-nodejs) 137 | -------------------------------------------------------------------------------- /docs/functional-components/internationalization.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # Internationalization 6 | 7 | ## Recommended Components 8 | 9 | - Built in to JavaScript 10 | 11 | Ecma-402/Ecma-262 support for `Intl` object and related functionality such as String.localeCompare [Node Intl.html](https://github.com/nodejs/node/blob/master/doc/api/intl.md) . Widely supported, growing feature set. Use the API when possible. (Also available on all major browsers.) These functions, in general, accept a Locale string (such as `en-CA` for English in Canada) to specify which language and cultural preference should be used. 12 | 13 | - Collation: language-sensitive comparison and sorting 14 | - Always use `String.localeCompare()` to compare textual content from users. 15 | - Date/Time and Number formatting: language-aware output of dates/times and numbers. 16 | 17 | - Upper/Lower casing and normalization: converting strings to a normalized or cased form… In many languages, there are multiple representations of the same character which will not compare as equal with `===` unless they are normalized. In Turkish, the uppercase of `i` is `İ` (with a dot), not `I` (without a dot). 18 | 19 | * Language data use by the above functions is bundled into the Node.js runtime As of Node.js 13. For versions prior to Node.js 13 20 | this data must be installed separately and configured as outlined in [providing icu data at runtime](https://github.com/nodejs/node/blob/master/doc/api/intl.md#providing-icu-data-at-runtime). We recommend using the [full-icu](https://www.npmjs.com/package/full-icu) module to install this data when needed. 21 | 22 | The built-in `Intl` does not currently support some of the functionality that may be required for an internationalized user experience. For example, a common requirement is to present a translated version of a message such as `You have ${count} messages.` Two components are required: 23 | 24 | - Resource Loading: A way to load the translated version of this message. The application must be able to find a suitable fallback if the user’s specific language and region is not available, possibly falling back to a different language if the message has not been translated yet. Other types of resources, such as images, may need to be loaded as well. 25 | 26 | - Message Format: Once a message is loaded, a library must be called to format this string, along with the parameter data, to produce the final string to display to the user. 27 | - English (Canada): `You have ${count} messages.` -> **You have 1,234 messages.** 28 | - Spanish (Spain): `Tienes ${count} mensajes.` -> **Tienes 1.234 mensajes.** 29 | - Note: that translation may require a re-ordering of the substituted components, and is also affected by specific plural rules in a particular language. 30 | 31 | For Resource Loading and Message Format, we recommend [i18next](https://www.i18next.com/) -- With >500,000 downloads a month, i18next is one of the most popular internationalization framework for Node.js. 32 | It provides the capabilities needed to manage strings within your application so that they can be 33 | displayed in the locale appropriate for the end user. It is also supported on the browser. 34 | 35 | - We recommend using i18next with the [i18next-icu](https://www.npmjs.com/package/i18next-icu) module so that ICU MessageFormat syntax is used. There is industry wide work to standardize on the MessageFormat syntax. For more details you can read about current progress [https://github.com/unicode-org/message-format-wg](https://github.com/unicode-org/message-format-wg). 36 | 37 | - For loading localized content, we recommend using [i18next-fs-backend](https://www.npmjs.com/package/i18next-fs-backend) which is a backend that allows you to load translated resources as JSON files from the filesystem. 38 | 39 | - If you are using express or a web framework that supports express middleware, [i18next-http-middleware](https://www.npmjs.com/package/i18next-http-middleware) 40 | provides support for language detection/management when using i18next. 41 | 42 | Translated Language and Region Names: Applications which display a list of languages or countries/regions to users often must translate that list into many other languages according to their ISO code. Using the industry-standard vetted [CLDR](https://unicode.org/cldr) data will avoid the need to manually maintain and translate such a list. We recommend that you use this data via its [NPM module](https://npmjs.com/package/cldr-localenames-full). For example, to fetch the name of "French" in "Spanish". Note that this is a large package, containing data for over 500 locales. 43 | 44 | ```shell 45 | $ npm i cldr-localenames-full 46 | $ node -p "require('cldr-localenames-full/main/es/languages').main.es.localeDisplayNames.languages['fr']" 47 | francés 48 | ``` 49 | 50 | Also Note that there is ongoing active work to move the above features into JavaScript. To see details or even to influence the priorities, see [github.com/tc39/ecma402](https://github.com/tc39/proposals/blob/master/ecma402/README.md#active-proposals). 51 | 52 | ## Guidance 53 | 54 | ### When to internationalize 55 | 56 | Internationalizing your application will require some extra work. If your company supports their applications across geographies it's beneficial 57 | to build in the internationalization components from the start. In addition, if it's a case of when the application will go into production 58 | versus if, it is also beneficial to build internationalization in from the start. 59 | 60 | On the other hand, for initial proof of concepts or limited releases where time to delivery is critical, the additional cost could prevent the project 61 | from being successful and it's accepted that hard coding strings is ok. The same is also often true for one-off demos and other 62 | similar short lived assets. 63 | 64 | ### Logging 65 | 66 | It is not recommended to translate low-level error and status messages. 67 | See [logging](../operations/logging.md) for additional guidance. 68 | -------------------------------------------------------------------------------- /docs/functional-components/message-queuing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 7 3 | --- 4 | 5 | # Message Queuing 6 | 7 | ## Recommended packages 8 | 9 | | Server | Recommended client | 10 | | -------- | ------------------ | 11 | | Kafka | [node-rdkafka][] | 12 | | Kafka | [KafkaJS][] | 13 | | ActiveMQ | [rhea][] | 14 | | Redis | [ioredis][] | 15 | 16 | ## Kafka 17 | 18 | It's currently difficult to make a single recommendation for a Node.js 19 | Kafka client. 20 | 21 | The team currently has the most real-world experience with 22 | [node-rdkafka][]. In the past it has been widely used and 23 | recommended by the messaging groups within the `teams` 24 | organizations for performance, features, and protocol compatibility. 25 | One of it's strengths is that is based on the same 26 | [librdkafka](https://github.com/edenhill/librdkafka), maintained 27 | by the Kafka project and used by most language clients. **However** 28 | it is in the midst of a maintenance challenge that it does not 29 | seem to be pulling out of (for example at the time this was written 30 | node-rdkafka does not build on Node.js version 16). 31 | 32 | [KafkaJS][] is a newer Node.js 33 | Kafka client which is more actively maintained and is growing in 34 | popularity. It's pure JavaScript implementation makes it 35 | easier to install and use. While we don't have past history of real-world 36 | experience with the KafkaJS client, we have reviewed the features 37 | and usage versus node-rdkafka and it compares favorably. The one 38 | potential caveat is with respect to performance where node-rdkafka, likely 39 | due to its use of [librdkafka](https://github.com/edenhill/librdkafka), 40 | comes out ahead. While the difference a simple benchmark is quite 41 | significant, whether that matters for a real-world application will 42 | depend on the application. 43 | 44 | At this point our recommendation is: 45 | 46 | - if you need the highest possible performance or longest track record of production use and are 47 | using an older version of Node.js (14.x or earlier) and can tolerate 48 | the risk on the maintenance side [node-rdkafka][] may still be 49 | your best choice. 50 | - otherwise you should consider [KafkaJS][]. If your application 51 | has high performance requirements you should plan to validate 52 | that you can meet those requirements with KafkaJS early on in your 53 | development lifecycle. 54 | 55 | ### Guidance 56 | 57 | Reuse connections. Do not write apps that connect/send/disconnect 58 | repeatedly in a loop. This will result in poor performance, not only for the 59 | individual application, but will also impact the Kafka cluster for other users. 60 | 61 | Architect applications so that they connect and keep 62 | an open connection on which events are processed when they arrive. 63 | 64 | ## ActiveMQ 65 | 66 | Recommendation is to use [rhea][] which supports AMQP1.0 67 | (one of the protocols supported by ActiveQ). This module is maintained by Red Hat and has 68 | higher weekly downloads than the competing module for ActiveMQ which supports the STOMP 69 | protocol (the native ActiveMQ protocol). 70 | 71 | ### Guidance 72 | 73 | ## Redis 74 | 75 | Recommendation is to use [ioredis][]. 76 | There are 2 good options with no clear technical winner, but IBM has experience 77 | in production with [ioredis][] so that is why it is recommended over [redis][]. 78 | 79 | ### Guidance 80 | 81 | If you are already using redis for messaging this can provide a low cost option 82 | but does not support more advanced features like High Availability. For more 83 | sophisticated uses cases you should consider a more complete option like Kafka. 84 | 85 | [@stomp/stompjs]: https://www.npmjs.com/package/@stomp/stompjs 86 | [amqplib]: https://www.npmjs.com/package/amqplib 87 | [ioredis]: https://www.npmjs.com/package/ioredis 88 | [node-rdkafka]: https://www.npmjs.com/package/node-rdkafka 89 | [redis]: https://www.npmjs.com/package/redis 90 | [ioredis]: https://www.npmjs.com/package/ioredis 91 | [rhea]: https://www.npmjs.com/package/rhea 92 | [kafkajs]: https://github.com/tulios/kafkajs 93 | -------------------------------------------------------------------------------- /docs/functional-components/nodejs-versions-images.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 8 3 | --- 4 | 5 | # Node.js Versions and Container Images 6 | 7 | ## Recommended Components 8 | 9 | | Distribution type | Recommended source | 10 | | --------------------------------- | -------------------------------------------------------- | 11 | | Raw binaries | [Node.js Download site](https://nodejs.org/en/download/) | 12 | | Windows, Mac Installers | [Node.js Download site](https://nodejs.org/en/download/) | 13 | | Version manager | [nvm](https://github.com/nvm-sh/nvm) | 14 | | Commercially Supported Binaries | OS Packages from OS vendor | 15 | | Binaries with FIPs support | OS Packages from OS vendor | 16 | | Containers | Official Docker images excluding Alpine | 17 | | Commercially Supported Containers | Images from distros (for example rhel or ubi images) | 18 | | Containers with FIPs support | Images from distros (for example rhel or ubi images) | 19 | 20 | We recommend that you use only [LTS](https://github.com/nodejs/release#release-phases) 21 | versions for production use, and in addition test on the latest `Current` in order 22 | to prepare for future upgrades. A new LTS version is available every October from the 23 | project and past LTS versions go EOL in April, 30 months after they were released. 24 | 25 | ### Raw binaries 26 | 27 | The Node.js projects provides binaries for the 28 | supported platforms on the [download](https://nodejs.org/en/download/) page. 29 | 30 | These are the most up to date packages available and new releases show 31 | up on this page first. 32 | 33 | ### Windows and Mac installers 34 | 35 | The Node.js projects provides installers for Windows and Mac 36 | on the [download](https://nodejs.org/en/download/) page. 37 | 38 | These are the most up to date installers available and new releases show 39 | up on this page first. 40 | 41 | ### Node.js version managers 42 | 43 | Node.js version managers provide an easier way to get Node.js 44 | versions from the Node.js download site and switch between them. 45 | The the teams organizations have the most experience with 46 | [nvm](https://github.com/nvm-sh/nvm) 47 | with the caveat that it does not support Windows and that 48 | it should only be used for development as opposed to production 49 | deployments. 50 | 51 | ### Commercially Supported Binaries 52 | 53 | Most often the easiest way to get support is from an operating system 54 | vendor. This generally requires using the binaries which are 55 | installed using the native package managers for that OS. 56 | 57 | **Note:** It is quite common for the version of Node.js which 58 | is installed in this way to be tied to the OS version. 59 | For example if you simply install `apt-get install nodejs` on 60 | Ubuntu 18.04 you get Node.js v8.10.0 which is already end of life (EOL). 61 | 62 | Therefore, it is generally not recommeneded that you use the default 63 | Node.js version provided by an OS package manager. Instructions 64 | on this [page](https://nodejs.org/en/download/package-manager/) may 65 | help in configuring so that you get an up to date version. 66 | 67 | For Red Hat and IBM deployments that need commercial support 68 | we recommend the binaries which come with RHEL. 69 | 70 | ### Binaries with FIPs support 71 | 72 | The community is at an awkward period where the only supported versions 73 | of OpenSSL do not have a FIPs certication. The community binaries 74 | and containers are, therefore, not suitable for deployments that 75 | need FIPs compliance. 76 | 77 | Several Operating system vendors have worked to include Node.js in 78 | the certification of their Operating systems and those are the 79 | recommended way to get a Node.js binaries for use where FIPs is 80 | a requirement. 81 | 82 | For Red Hat and IBM deployments that need FIPs support 83 | we recommend the binaries which come with RHEL. 84 | 85 | ### Container images 86 | 87 | Container images are docker images which have the Node.js binaries already 88 | bundled into the container. 89 | 90 | The Node.js [docker](https://github.com/nodejs/docker-node) team works with docker hub 91 | to maintain as set of `official` nodejs docker images on hub.docker.com - 92 | https://hub.docker.com/_/node 93 | 94 | Images are provided for: 95 | 96 | - debian 97 | - debian-minimal 98 | - alpine 99 | 100 | There are two image flavors based on debian so that you can achieve smaller container 101 | sizes using [multi-stage docker builds](https://docs.docker.com/develop/develop-images/multistage-build/). 102 | The larger images has all of the tools need to build the application while 103 | the minimal image has only the base components needed to run Node.js. In both cases 104 | these images bundle in the binaries which are available on the Node.js download 105 | site and support multiple ptatforms (x64, PPC and s390). 106 | 107 | Images are also provided for Alpine which can allow you to achieve even smaller 108 | images sizes. **However**, if you check the 109 | [BUILDING.md](https://github.com/nodejs/node/blob/master/BUILDING.md) 110 | file for the Node.js project you'll see that support for Alpine is `experimental`. 111 | This also means that there is no binary which can be bundled and instead 112 | the creation of the Alpine containers includes building the binaries 113 | themselves. For these reasons we don't recommend using the Alpine images 114 | unless the smaller size is an absolute requirement. 115 | 116 | ### Commercially Supported Containers 117 | 118 | Most often the easiest way to get support is from an operating system 119 | vendor. This generally requires using a host running an operating 120 | system from the vendor as well as containers from that vendor which 121 | include the Node.js binaries. 122 | 123 | For example, if you want to take advantage of the support for 124 | Node.js that comes with RHEL or Red Hat Runtimes you will need to use 125 | the rhel or ubi images available from the 126 | [Red Hat container catalog](https://catalog.redhat.com/software/containers/search?q=ubi%20node.js) 127 | 128 | ### Containers with FIPs support 129 | 130 | The community is at an awkward period where the only supported versions 131 | of OpenSSL do not have a FIPs certication. The community binaries 132 | and containers are, therefore, not suitable for deployments that 133 | need FIPs compliance. 134 | 135 | Several Operating system vendors have worked to include Node.js in 136 | the certification of their Operating systems and those are the 137 | recommended way to get a Node.js containers for use where FIPs is 138 | a requirement. 139 | 140 | For Red Hat and IBM deployments that need FIPs support 141 | we recommend the rhel and ubi Node.js containers. 142 | 143 | ## Guidance 144 | 145 | When possible deploy using containers versus managing the Operating system 146 | and Node.js binaries yourself. This will simplify upgrades and security 147 | response handling. 148 | 149 | Always cache the binaries, containers or OS packages tha you use in 150 | production and in build/test pipelines. For example, do not depend 151 | on the Node.js download site being available 24/7. 152 | 153 | Subscribe to the [nodejs-sec](https://groups.google.com/g/nodejs-sec) mailing list. 154 | This low volumne mailing list is used to provide advance notice of security 155 | releases and will give you the earliest warning that you may need 156 | to update your Node.js version. 157 | 158 | For new applications always start with the latest LTS version. 159 | 160 | For existing applications plan to do advance testing on your next 161 | target LTS version when it is released in April each year (it will be the 162 | `Current` for 6 months before being promoted to LTS at the end of 163 | October) and then put it into production in January the following year. 164 | This will ensure you can ensure that any issues specific to your 165 | deployment can be reported/addressed by the project before it 166 | becomes LTS and ensure you have enough time before the existing LTS 167 | version you are using goes EOL in April. 168 | -------------------------------------------------------------------------------- /docs/functional-components/rest-api-development.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # REST APIs Development 6 | 7 | Building [RESTFull](https://www.redhat.com/en/topics/api/what-is-a-rest-api) APIs is a typical use 8 | case for Node.js. There are two typical approaches: 9 | 10 | * API First - define the API, use tools to help scaffold and then fill in the implementation. 11 | * Code First - implement the APIs and then generate documentation based on exposed API 12 | 13 | The team's experience is that the API first approach based on [OpenAPI](https://swagger.io/specification/) 14 | provides benefits in both initial implementation and maintenance and our recommended packages and 15 | guidance is based on that approach, particularly if one or more of the following are true: 16 | 17 | - New project without existing API 18 | - Client side and backend are developed by different teams that need way to communicate API changes 19 | - Development on clients and backends starts around the same time giving developers ability to mock API based on OpenAPI spec 20 | 21 | > NOTE: This section of the reference architecture focuses on building RESTfull APIs. 22 | For GraphQL please refer to the [GraphQL Guide][] section. 23 | 24 | ## "API-first" approach 25 | 26 | With the API-first approach, designing the API is the first priority before writing any code. Design of the API involves thorough thinking and planning through collaboration with different teams (both client and backend side). This results in high-level documentation describing the intent of the API and ability to build client without waiting for server to be finished. 27 | 28 | This API contract acts as a central draft keeping all your team members aligned on what your API’s objectives are and how your API’s resources are exposed. The finalization of the contract allows the team to build the interface of the application. 29 | 30 | After this, the cross-functional teams rely on this interface to build the rest of the application independent of each other. In practice, teams can generate backends stubs and fully functional client libraries to avoid deviation from specification set in the OpenAPI spec file. 31 | 32 | ## Code First vs API first 33 | 34 | Code first approach provides libraries that understand server side backend structure and generate respective OpenAPI files. 35 | In this approach full control over API lies within server side team - generated OpenAPI file is read only and cannot be effectively 36 | used to negotiate API between client and server. 37 | 38 | API first approach uses OpenAPI file as source of truth. Both client and server side generate code based on the OpenAPI file. 39 | 40 | ## Recommended Packages 41 | 42 | List bellow provides comprehensive set of libraries that can be used for an end to end full stack application written in Node.js, 43 | Express.js as well as client side applications. 44 | 45 | ### Code Generation Tools 46 | 47 | [openapitools/openapi-generator-cli](https://www.npmjs.com/package/@openapitools/openapi-generator-cli) 48 | This CLI provides support for generating source code based on the OpenAPI spec. The project that 49 | provides this cli for JavaScript also provides generators for a number of other 50 | languages as well. This CLI has widespread usage across industry including many community projects at Red Hat. 51 | The project is maintained by OpenAPI Generator Community and you can read the documentation 52 | here:- . It can be used as both a backend and client generator as follows: 53 | 54 | **backend generator** 55 | 56 | The nodejs-express-server option can be used to generate Express.js based stub 57 | implementations based on your OpenAPI file. 58 | ```bash 59 | npx @openapitools/openapi-generator-cli generate -g nodejs-express-server -i yourapi.json -o ./yourproject 60 | ``` 61 | 62 | **Client generator** 63 | 64 | The typescript-node option can be used to generate a client for Node.js applications 65 | that allows us to perform requests against another backend 66 | 67 | ```bash 68 | npx @openapitools/openapi-generator-cli generate -g typescript-node -i yourapi.json -o ./yourproject 69 | ``` 70 | 71 | ### API mocking 72 | 73 | [openapi-backend](https://www.npmjs.com/package/openapi-backend) allows you to mock based 74 | on an OpenAPI definition by returning predefined strings. The library provides way not only 75 | return predefined stubs but also perform validation or handle different use cases depending on request 76 | 77 | [@stoplight/prism-cli](https://www.npmjs.com/package/@stoplight/prism-cli) allows you to 78 | automatically mock API using OpenAPI spec definitions. This package is recommended if you 79 | need is an out of the box way to mock API without any development involved. 80 | 81 | ### API validation middleware 82 | 83 | [express-openapi-validator](https://www.npmjs.com/package/express-openapi-validator) is a validator 84 | for express middleware that some of the build have used successfully. 85 | 86 | ### Creating/editing OpenAPI Specifications 87 | 88 | [swagger-editor](https://www.npmjs.com/package/swagger-editor) is the most popular editor 89 | which can be embedded into an existing server or run standalone. If you want to edit your 90 | specifications in YAML, you can use the 91 | [openapi-editor](https://www.npmjs.com/package/openapi-editor) wrapper. 92 | 93 | [vscode-openapi](https://github.com/42Crunch/vscode-openapi) is a VScode plugin for 94 | building and validation of OpenAPI files that members of the team using vscode 95 | have used successfully. 96 | 97 | ## Guidance 98 | 99 | Based on the teams experience we recommend the following: 100 | 101 | 1. Define the API using OpenAPI 3.0 or 3.1, you can write the OpenAPI definitions in YAML or JSON formats, the team does not have a preference for one over the other. 102 | 2. Prefer generating code from OpenAPI file for both client and server. Generating code based on the specification will ensure that the same types, formats are used. This will enable your team to iterate on the specification without worry of getting out of sync. 103 | 3. When making changes in the OpenAPI file change it's [version](https://github.com/OAI/OpenAPI-Specification/blob/main/examples/v3.0/petstore-expanded.yaml#L3). Changed version will help others to detect what kind of changes were made. 104 | 4. When introducing breaking changes consider adding them as new endpoints by introducing another v2 prefix in the API path. 105 | 5. Every path should have `operationId` field specified. This field is used by generator to generate method names for clients etc. 106 | 6. When building response objects prefer referencing predefined Objects and Enums in [Schemas](https://swagger.io/docs/specification/data-models/) 107 | 7. If an API returns a specific [error object](https://github.com/OAI/OpenAPI-Specification/blob/main/examples/v3.0/petstore-expanded.yaml#L148-L158) it should be defined in the Schemas. 108 | 8. Declare servers and security scheme to enable users to call API from OpenAPI Editor and other tools. 109 | 9. Use [tags](https://swagger.io/docs/specification/grouping-operations-with-tags/) to define namespaces for your API. Grouping operations with tags that will be used to organize your generated source code into folder structure. 110 | 111 | ### A good example 112 | 113 | OpenAPI spec provides an complete and minimalistic [PetStore](https://github.com/OAI/OpenAPI-Specification/blob/main/examples/v3.0/petstore-expanded.yaml) example. This example follows all the best practices and patterns for building API. 114 | 115 | [GraphQL Guide]: https://nodeshift.dev/nodejs-reference-architecture/functional-components/graphql 116 | -------------------------------------------------------------------------------- /docs/functional-components/scaling-multi-threading.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 9 3 | --- 4 | 5 | # Load balancing, Scaling and Multi-threading 6 | 7 | Node.js is said to be `single-threaded`. While not quite true, it reflects that 8 | most work is done on a single thread running the event loop. The asynchronous 9 | nature of JavaScript means that Node.js can handle a larger number of 10 | concurrent requests on that single thread. 11 | 12 | At the same time that does not mean that Node.js applications/solutions are 13 | `single-threaded`. Today's computers provide multiple concurrent threads of 14 | execution (either with multiple cores and/or cores that can support 15 | multiple concurrent threads of execution) and Node.js applications have 16 | long exploited those additional threads by running multiple Node.js instances. 17 | 18 | Mutiple threads within a single machine can typically either be exploited within 19 | a single process or by starting multiple processes. There are advantages 20 | and dis-advantages to each. 21 | 22 | Processes provide better isolation but also lower 23 | opportunities to share resources and makes communication between threads 24 | more costly. While using multiple threads within a process may be able to 25 | scale more efficiently within a single process it has the hard limit 26 | of only being able to scale to the resources provided by a single machine. 27 | 28 | With container based deployments the number of threads available may 29 | also be limited, with the assumption that when additional cpu resources 30 | are needed, additional containers will be created and the load 31 | spread across those containers. 32 | 33 | Today's cloud native deployments generally have a goal to be able to 34 | scale to a level that that cannot be met through by the 35 | resources/availability that can be achieved on a single machine. This 36 | naturally favors scaling by adding additional copies of a container, 37 | each of which, is typically running a single process. 38 | 39 | The small footprint and fast startup of Node.js, along with the 40 | ability to handle many concurrent requests without needing multiple 41 | threads of execution and synchornization between those threads makes 42 | it a good fit for todays approach to scaling using containers. 43 | 44 | ## Recommended Components 45 | 46 | We don't recommened any specific components at this time. 47 | 48 | ## Guidance 49 | 50 | - when possible applications should be decomposed so that a 51 | request to a single container will need no more than single 52 | thread of execution in order to complete in a reasonable time. 53 | When necessary to achieve this, consider further decomposing 54 | the application. If this is not reasonable, 55 | [WorkerThreads](https://nodejs.org/api/worker_threads.html) 56 | are recommended versus multiple processes in the same container. 57 | 58 | - delegate management of the containers supporting 59 | the application and the load balancing/routing of requests 60 | to those containers to the highest layer possible. For 61 | example, if the application is deployed to kubernetes, 62 | do not use tools like the 63 | [Cluster API](https://nodejs.org/api/cluster.html) to manage 64 | requests within a container, instead rely on the facilities 65 | provided by kubernetes. In our experience this has been 66 | just as efficient in terms of machine resources and allows 67 | better scaling. 68 | 69 | - Avoid blocking the event loop for a prolonged period 70 | of time. If you have a mix of request types where some are long 71 | running, consider moving the long running requests so that they 72 | execute in their own set of containers in order to enable better 73 | scaling. However, even once moved it often makes sense to use 74 | [WorkerThreads](https://nodejs.org/api/worker_threads.html) to 75 | run the long running request in order to 76 | avoid blocking the main event loop. This is to prevent 77 | long running requests on the main event loop from stalling 78 | requests to health monitoring, metrics and similar endpoints 79 | that need to be supported by a containter. 80 | 81 | - When using [WorkerThreads](https://nodejs.org/api/worker_threads.html) 82 | make sure you pool worker threads (for example 83 | by using something like [piscina](https://www.npmjs.com/package/piscina) 84 | and ensure you preserve ascync context for requests with 85 | [AsyncResource](https://nodejs.org/api/async_hooks.html#async_hooks_class_asyncresource) 86 | if you don't use an existing pooling library like piscina which 87 | does this for you. 88 | 89 | - [WorkerThreads](https://nodejs.org/api/worker_threads.html) 90 | may also be appropriate if your application 91 | must run as a single process (for example a desktop application). In these 92 | cases it is known that you cannot scale beyond the resources of the single 93 | machine and it is often preferrable to have the application show up 94 | as a single processes versus many individual processes. 95 | -------------------------------------------------------------------------------- /docs/functional-components/static-assets.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 10 3 | --- 4 | 5 | # Static assets 6 | 7 | ## Strategies 8 | 9 | There are different strategies when dealing with assets/resources in a Node.js application: 10 | 11 | ### Static only content 12 | 13 | If your application has only client JavaScript, like a Single Page Application (SPA), look no further. You most likely do not need to use Node.js to host the static content. You can use web servers or object storage like `nginx`, `Apache`, `COS`, `S3`, etc, and front that system with caching (CDN). 14 | 15 | ### Application with dynamically growing content (user generated content) 16 | 17 | If your application has primarily server logic, but with growing content, consider using Node.js in combination with an external storage system like `COS` or `S3`. For example, if you have a Node.js application for uploading images, instead of saving images to the file system, consider saving images to object storage. This is a more scalable approach compared to saving images on the file system, which can grow beyond the infrastructure. 18 | 19 | ### Application with frontend 20 | 21 | If your application has client and server logic, then you should consider using Node.js web server (express) with static middleware. It is a best practice to couple your frontend and backend together as a single, deployable artifact. Doing so addresses concerns such as: 22 | 23 | - Syncing assets to external environments (CDNs, object storage, etc) 24 | - Deploying artifact to different environments (because the assets are self contained, no issues with syncing) 25 | - Able to use same domain for HTTP2 26 | 27 | Read futher for additional guidance on using cache-control headers for static assets. 28 | 29 | ## Recommended packages 30 | 31 | - [express.static][]: `express.static` is part of the Express.js package that allows developers to expose static middlewares. 32 | 33 | ## Guidance 34 | 35 | For serving static resources on the application, we recommend using [express.static][] middleware as it has been widely used and tested in production. 36 | 37 | When using `express.static()` method, we can serve static resources directly by specifying the folder name where we have stored our static resources. 38 | 39 | Documentation for the middleware can be found [here][express.static] 40 | 41 | ### Caching 42 | 43 | The static middleware allows caching of static resources via exposed [caching-headers][]. 44 | 45 | Origin servers communicate caching instructions via the header `Cache-Control`. The values of `Cache-Control` are called directives. Example directives include: `max-age`, `no-store, no-cache, must-revalidate`, `public, private`, etc. 46 | 47 | Freshness control of the resource happens in cache and is based on time. The validation that happens on origin server is based on time and identifiers (ETags). It is important to have ETag header on all HTTP resources (better/stronger than time based header). 48 | 49 | #### Common Directive Use Cases 50 | 51 | Note: Upstream systems can be picky about interpreting directives for caching. You may have to read documentation for the particular system (Akamai, Fastly, Google CDN, Cloudflare, nginx, varnish) to verify valid directives. 52 | 53 | ##### Caching static assets for a year 54 | 55 | Cache static assets for a year if the filename and contents are uniquely generated 56 | 57 | ``` 58 | Cache-Control: public, max-age=31536000 59 | 60 | ``` 61 | 62 | If `Cache-Control` does not have max-age, it will respect Expires header 63 | 64 | ``` 65 | Cache-Control: public 66 | Expires: Sat, 13 Feb 2022 07:00:00 GMT 67 | ``` 68 | 69 | ##### Caching HTTP resources only on browser 70 | 71 | In some cases, we want to force cache only for the browser and not for CDN or other upstream caches. 72 | 73 | ``` 74 | Cache-Control: private 75 | ``` 76 | 77 | ##### No caching allowed 78 | 79 | Force upstream to not cache at all. Useful if you need to ensure that an HTTP resource always goes to origin (for example, if the HTTP resource varies due to a cookie and the endpoint is common to all users) 80 | 81 | ``` 82 | Cache-Control: no-store, no-cache, must-revalidate 83 | ``` 84 | 85 | #### Advanced Caching Guidance 86 | 87 | For more advanced use cases, caching can be controlled independently of the `Cache-Control` headers. Depending on upstream caching system, you can configure `Cache-Control` header from origin to the CDN, and configure a separate set of caching rules for downstream (the browsers). 88 | 89 | Say for example your application contains pages/resources that change depending on a user's logged in state. It is important that `Cache-Control` is not cached on the browser, however we can still cache at the edge and control the "cache key" based on unique identifiers (such as a userId). 90 | 91 | This ensures less hits to origin, takes advantage of caching at the edge, and removes the potential for bad user experiences due to aggressively cached pages. 92 | 93 | If the application contains uniquely different pages/resources from a non-logged in user, you could keep `Cache-Control` with `private, max-age=300` (or max-age as appropriate based on content and session expiration). 94 | 95 | ### Naming Static Assets 96 | 97 | If you configured your static middleware to use client side caching please make sure that 98 | every modification in your code will be creating resources with different filename. 99 | 100 | When using bundlers you will explicitly need to generate different filenames every time content changes. If hash is used in filename, caching directives can be set as long as a year. 101 | 102 | Example for webpack (most popular bundler) can be found [here][webpack-caching]. 103 | 104 | [caching-headers]: https://www.freecodecamp.org/news/an-in-depth-introduction-to-http-caching-cache-control-vary/ 105 | [express.static]: https://expressjs.com/en/4x/api.html#express.static 106 | [webpack-caching]: https://webpack.js.org/guides/caching 107 | -------------------------------------------------------------------------------- /docs/functional-components/template-engines.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 11 3 | --- 4 | 5 | # Template Engines (Server Side) 6 | 7 | ## Recommended packages 8 | 9 | No recommended packages. 10 | 11 | ## Guidance 12 | 13 | Server side templating is no longer common for creating UIs, and has never been 14 | common for implementing microservice APIs. 15 | 16 | React and Angular have alternatives to templating (Server Side Rendering, SSR). 17 | 18 | If a template engine is included in a toolset, then it doesn't have to be 19 | chosen, the recommendation would be to use the one provided (for example, 20 | [eleventy](https://www.11ty.dev/) uses 21 | [Nunjucks](https://mozilla.github.io/nunjucks/) and 22 | [Express](https://expressjs.com/) supports a number of options 23 | including [ejs](https://ejs.co/)). 24 | -------------------------------------------------------------------------------- /docs/functional-components/transaction-handling.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 13 3 | --- 4 | 5 | # Transaction Handling 6 | 7 | Transactions are a common requirement for applications. They 8 | are needed when you want a set of updates either to all 9 | succeed or fail as a group. For a nice intro to some of 10 | the concepts check out 11 | [Transactions](https://cs.uwaterloo.ca/~tozsu/courses/CS338/lectures/15.%20Transactions.pdf). 12 | 13 | 14 | ## Recommended packages 15 | 16 | None 17 | 18 | ### General Guidance 19 | 20 | Unlike in the Java ecosystem, there are no well-established application 21 | servers that support transactions and no JavaScript specific standards 22 | for transactions. 23 | 24 | However, this does not mean that you cannot use transactions with 25 | Node.js. Many of the databases and the recommended clients covered 26 | in the [databases](./databases.md) section support transactions. 27 | This makes it relatively easy to update multiple elements 28 | with the database within a transaction. Typically 29 | the clients provide a simple API to start, commit and rollback 30 | transactions or the equivalent can be done by submitting queries 31 | through the same APIs used to query and update data. Since 32 | these APIs vary by database, consult the documentation for the 33 | database you are using. As an example this 34 | [section in the Node.js pg client documentation](https://node-postgres.com/features/transactions) 35 | shows how to handle rollback when using transactions. 36 | 37 | In the team's experience transactions work best with async/await versus 38 | generators and it is good to have a try/catch around the 39 | rollback sections in addition to those which do the commit. 40 | 41 | Node.js applications are often structured to use microservices 42 | instead of a monolith which may limit the ability to leverage 43 | the transaction support in databases as not all elements 44 | being updated are updated through the same database 45 | connection. The related challenges are not specific to 46 | Node.js and there are common techniques that are used 47 | including: 48 | * [2 phase commit](https://www.educative.io/answers/what-is-the-two-phase-commit-protocol) 49 | * [Saga pattern](https://medium.com/trendyol-tech/saga-pattern-briefly-5b6cf22dfabc) 50 | 51 | In the teams experience Node.js applications will most often use the 52 | Saga pattern as opposed to 2 phase commit. When 2 phase commit is 53 | used it will have to depend on external support from an underlying 54 | data store. Some databases offer support to help with implementing 55 | the 2 phase commit technique, so read through the documentation for the 56 | database you are using if you are planning to use that technique. 57 | 58 | If you want to read more in depth about these techniques 59 | and which one you might want to use, 60 | [Saga: The new era of transactions in a microservices architecture](https://www.redhat.com/files/summit/session-assets/2019/T42224.pdf) 61 | covers them in more depth. 62 | 63 | Some databases offer support to help with implementing 64 | the 2 phase commit technique, so read through the documentation for the 65 | database you are using if you are planning to use that technique. 66 | 67 | ## Further Reading 68 | 69 | * [Introduction to the Node.js reference architecture: Testing](https://developers.redhat.com/articles/2023/07/31/how-handle-transactions-nodejs-reference-architecture) 70 | -------------------------------------------------------------------------------- /docs/functional-components/webframework.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 12 3 | --- 4 | 5 | # Web Framework 6 | 7 | ## Recommended Components 8 | 9 | - The team has past success with Express - https://expressjs.com/ and it continues to 10 | be broadly used in the ecosystem with 29 million weekly downloads. 11 | - There are other frameworks that are gaining on Express and may be a good fit for your deployments. 12 | The team has had success with some of them, however, there is still no clear 13 | successor to express. For a good overview of some of the other frameworks and considerations for 14 | selecting a web framework you can check out this article - [introduction-nodejs-reference-architecture-part-6-choosing-web-frameworks](https://developers.redhat.com/articles/2021/12/03/introduction-nodejs-reference-architecture-part-6-choosing-web-frameworks) 15 | 16 | ## Guidance 17 | 18 | When deploying Express we have the following additional recommendations: 19 | 20 | - Use the latest version of the 4.x release line. This version is currently the most suitable for production use. 21 | We recommend using ~4.x.y (where x.y reflects the version you start at) in your package.json so that you get patch 22 | version updates as you update your application in development. We recommend planned periodic reviews 23 | to decide when to update to new minor versions. 24 | 25 | - Use different ports for different concerns when possible. 26 | An application can provide additional endpoints for metrics collection or other concerns. It is recommended that 27 | the main port (for example 3000 or 8080) be reserved for business logic and an admin 28 | port be used for supporting endpoints. This helps to separate out requests to business logic and makes it easier to collect 29 | data specific to requests to the business logic. 30 | 31 | - Use an environment variable to define the port for the business logic and for the admin port. 32 | We recommend you use `PORT` and `ADMIN_PORT` as the names. We also recommend that the default ports be `8080` (business) and `9080` (admin). 33 | 34 | - Include a liveness and readiness endpoint even if not deploying initially to kubernetes. These endpoints are useful in environments 35 | other than kubernetes for problem determination and monitoring. See the section on "Health Checks" for more information. 36 | 37 | - Define global middleware before routes. Not doing so is a common mistake that can result in middleware not running when expected. 38 | 39 | - Use Helmet (https://www.npmjs.com/package/helmet) to set HTTP headers for a basic level of protection from some common attacks. 40 | 41 | - Make testable for application testable by: 42 | 43 | - Breaking out logic into smaller components and routes 44 | - Define a "test" entry in the "scripts" section of the package.json for your applications which runs the units tests. 45 | 46 | - See the sections on Logging and Authentication for further recommendations 47 | 48 | - Leverage [CLI](https://nodejs.org/api/cli.html#cli_max_http_header_size_size) or [NODE](https://nodejs.org/api/cli.html#cli_node_options_options) options to increase HTTP headers size. There may be circumstances when cookies pollute header size beyond the 8KB default limit. For such cases, adding `--max-http-header-size=32768` to command line arguments when running the Node.js script will increase the header size. Alternative method is to leverage NODE_OPTIONS environment variable: `NODE_OPTIONS='--max-http-header-size=32768'` 49 | 50 | - When changing the max header size, take note of additional upstream clients. As an example, ingresses such as Nginx or even a CDN such as Akamai may need config changes to support the increased header size. 51 | 52 | 53 | ## Further Reading 54 | 55 | [Introduction to the Node.js reference architecture: Choosing Web Frameworks](https://developers.redhat.com/articles/2021/12/03/introduction-nodejs-reference-architecture-part-6-choosing-web-frameworks) 56 | -------------------------------------------------------------------------------- /docs/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | slug: / 4 | --- 5 | 6 | # Node.js Reference Architecture 7 | 8 | ## Overview 9 | 10 | The goal of the Node.js reference architecture is to present 11 | the `teams` 'opinion' on what components our customers 12 | and internal teams should use when building Node.js applications 13 | and guidance for how to be successful in production with those components. 14 | 15 | Traditionally there has been reluctance to recommend a subset 16 | of the packages the JavaScript ecosystem but our customers are increasingly 17 | looking to the `team` for an opinion of where to start. 18 | 19 | The components in this architecture are what we recommend to help internal 20 | and external customers get started based on our experience. Other components may be equally 21 | good, but these are the ones we know best and have the most experience with. 22 | 23 | - Where possible the opinion is based on what we've used internally and in our customer engagements. 24 | - The components specified will be our first priority for our contributions to open source projects in the JavaScript ecosystem. 25 | - Due to the above these are the components the `team` is best positioned when working with internal and external customers. 26 | However, we do not include formal support for these components in any of our support offerings unless specifically identified 27 | in those offerings. 28 | - The recommended components may change over time as technologies and approaches change. 29 | 30 | If you want to learn more about some of the discussions that went into the Node.js reference architecture you can check out the [Introduction to the Node.js reference architecture](https://developers.redhat.com/blog/2021/03/08/introduction-to-the-node-js-reference-architecture-part-1-overview) blog post series. 31 | 32 | The content of the reference architecture is managed in this github repository: https://github.com/nodeshift/nodejs-reference-architecture. 33 | 34 | ### The team 35 | 36 | The `team` consists of engineers from across groups within IBM and Red Hat who: 37 | 38 | - are actively engaged in the JavaScript/Node.js community 39 | - have large Javascript/Node.js deployments 40 | - provide consulting advice and/or development related to JavaScript/Node.js for customers 41 | - develop/deliver JavaScript or Node.js components 42 | 43 | ### Key tenets 44 | 45 | - Whenever possible components should have been validated at scale within the `team's` 46 | JavaScript/Node.js deployments or in engagements with our customers. 47 | - We need to consider licensing and other due diligence when selecting components. 48 | - We are going to start with a focus on the back-end, a similar effort for front-end 49 | components will make sense as a follow on. 50 | 51 | -------------------------------------------------------------------------------- /docs/operations/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Operations", 3 | "position": 3 4 | } 5 | -------------------------------------------------------------------------------- /docs/operations/distributed-tracing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Distributed Tracing 6 | 7 | ## Recommended Components 8 | 9 | Distributed tracing typically requires a mechanism for collecting traces (instrumentation) 10 | and a separate mechanism for reporting and visualizing those traces. 11 | 12 | - [OpenTelemetry](https://opentelemetry.io/) provides instrumentation in multiple languages 13 | including Node. OpenTelemetry is not yet released as a final stable version and is in Beta. 14 | OpenTelemetry replaces both OpenTracing and OpenCensus, neither of which are actively being 15 | developed (security fixes only). 16 | 17 | For adding instrumentation to Node applications and services: 18 | 19 | - [@opentelemetry/sdk-trace-base](https://www.npmjs.com/package/@opentelemetry/sdk-trace-base) 20 | - [@opentelemetry/sdk-trace-node](https://www.npmjs.com/package/@opentelemetry/sdk-trace-node) - See the 21 | [Getting Started Guide](https://opentelemetry.io/docs/instrumentation/js/getting-started/) 22 | 23 | Reasons for choosing OpenTelemetry: 24 | 25 | - the open source tracing library that's replacing both OpenCensus and OpenTracing 26 | - handles basic use cases really well, includes good default configuration for most use cases 27 | - includes support for newer efficient Node implementation for correlating outbound traffic 28 | to incoming requests 29 | - supports multiple languages for tracing (not just Node) with a consistent API. 30 | 31 | ## Guidance 32 | 33 | There is significant value in collecting distributed tracing as it: 34 | 35 | - allows easy identification of performance critical services and code 36 | - allows quick navigation to failing calls that are "buried" deep in the system 37 | - allows a clearer understanding of the interdependencies of complicated systems 38 | 39 | These benefits come at a cost in: 40 | 41 | - adding instrumentation to each application and the related negligible application overhead 42 | - significant additional network and storage utilization 43 | - additional services, and the related administration (Jaeger/ElasticSearch, etc.) 44 | 45 | For non-trivial systems the benefits are typically worth the costs, especially when investigating 46 | problems. 47 | 48 | OpenTelemetry allows the ability to sample a subset of traces to reduce the storage and network 49 | utilization of the tracing data. The guidance here is that, where possible, sampling should be disabled 50 | such that all traces are recorded. If sampling is enabled, it is inevitable that the trace data is 51 | missing when trying to investigate some critical failure. 52 | 53 | Be aware that: 54 | 55 | - some error conditions that do not trigger network traffic are not traced (e.g. DNS lookup 56 | failures, etc.) 57 | - existing instrumentation libraries are not customizable (no hooks, or extension points - 58 | not able to extend instrumentation to add additional data without reimplementing them) 59 | - you are not able to post process traces from instrumentation prior to exporting them 60 | - you are not able to easily change configuration options dynamically (enabling/disabling tracing) 61 | 62 | ### Infrastructure 63 | 64 | - [Jaeger](https://www.jaegertracing.io/) provides visualization of distributed traces. 65 | - [ElasticSearch & Kibana](https://www.elastic.co/elastic-stack) provides storage for persisting 66 | the data behind Jaeger as well as alternate mechanisms in Kibana to search, visualize, and manage 67 | that data. 68 | - An alternate for Jaeger is [Zipkin](https://zipkin.io/) which is also directly supported by 69 | OpenTelemetry for visualizing distributed traces. The instrumentation in Node is not impacted 70 | by the selection of the visualization tool. Both Jaeger and Zipkin can be used concurrently if 71 | storage space is available. If using Zipkin, [Cassandra](https://cassandra.apache.org/) may be used 72 | instead of ElasticSearch. 73 | 74 | ### Integration suggestions 75 | 76 | Data management becomes a critical aspect of distributed tracing. Consider: 77 | 78 | - expiring data as it ages out and is no longer relevant 79 | - volumes and network traffic can become excessive 80 | - storage costs can be large. 81 | 82 | OpenTelemetry by default installs instrumentation patches for many communication protocols 83 | (HTTP, HTTPS, GPRC, etc.). Configure OpenTelemetry to install just those patches for protocols that are 84 | actively used in your applications. 85 | 86 | OpenTelemetry can be installed in container-based systems like Kubernetes. When used in conjunction with 87 | Istio care needs to be taken to ensure that either: 88 | 89 | - Istio distributed tracing is disabled 90 | - Istio distributed tracing is enabled and also exports all trace data to the same systems as OpenTelemetry. 91 | Additionally, since Istio is typically the entry point for new connections, it is what sets the 92 | sampling conditions for traces, and not OpenTelemetry. Ensure sampling in Istio is correctly configured. 93 | If Istio distributed tracing is enabled, but not exported to the same systems as OpenTelemetry, it 94 | will cause gaps and orphans in the tracing hierarchies. 95 | -------------------------------------------------------------------------------- /docs/operations/failurehandling.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Fault Tolerance 6 | 7 | ## Recommended Components 8 | 9 | We recommend that you first investigate if your environment supports a service mesh like [Istio](https://istio.io/). 10 | In that case it's recommended to leverage the capabilities of the mesh in order to handle fault tolerance. 11 | 12 | If your environment does not support a service mesh then we recommend the [Opossum](https://www.npmjs.com/package/opossum) module. It is the most widely used fault tolerance Node.js module, has no dependencies and has good community support. Opossum is a Node.js circuit breaker that executes asynchronous functions and monitors their execution status. When things start failing, opossum plays dead and fails fast. In addition you can provide a fallback function to be executed when in the failure state. 13 | 14 | The metrics that opossum collects can easily be fed into the companion [Prometheus](https://www.npmjs.com/package/opossum-prometheus) module in order to feed data in the [recommended metrics collection framework](https://github.com/rh-ibm-synergy/Nodejs-reference-architecture/blob/add-circuit-breaker/metrics.md). 15 | 16 | ## Guidance 17 | 18 | Many applications and services make calls to external services. Due to the asynchronous nature of Node.js, in most cases when an external call fails the best way to handle the failure is to propagate the failure back up the call chain, often resulting in an error being returned to the user of your application or caller of your service. This is true for Node.js as an asynchronous call which is blocked waiting for a response does not prevent other requests from being handled as would be the case for other runtimes which consume a thread for each active request. 19 | 20 | In specific cases, however, it is better to either: 21 | 22 | - retry the failed call 23 | - avoid repeating the call for some period of time and return an error up the call stack 24 | - avoid repeating the call for some period of time and use cached data to provide potentially degraded service 25 | 26 | The technique for implementing the last two is often called a `circuit breaker`. The basic idea behind the circuit breaker is that you wrap a protected function call in a circuit breaker object, which monitors for failures. Once the failures reach a certain threshold, the circuit breaker trips and enters the `open` state, and all further calls to the circuit breaker return with an error, without the protected call being made at all. 27 | 28 | Circuit breakers are recommended in the following situations: 29 | 30 | - repeated calls to the external service will worsen the situation, making it take longer for the external service to 31 | resume normal operation. If callers can cope with cached data then return that, otherwise simply return an error up 32 | the call chain while in the `open` state. 33 | - the application can cope by using cached data, and it is known that the external service takes time to ramp up capacity 34 | in the face of increasing numbers of requests. 35 | - There is a persistent occasional intermittent failure in the external service and a retry is the only way to avoid 36 | returning intermittent errors. In this case it is important to use a circuit breaker to limit the number of retries. 37 | - It is more important to return a response within a fixed maximum upper bound (even if that response is an error or a 38 | previously cached result) than it is to return live data. 39 | 40 | Examples of how to configure opossum circuit breakers are available in the main opossum [repo](https://github.com/nodeshift/opossum#usage). 41 | 42 | More detailed examples are available in the following starters: 43 | 44 | - https://github.com/nodeshift-starters/nodejs-circuit-breaker 45 | - https://github.com/nodeshift-starters/opossum-examples 46 | -------------------------------------------------------------------------------- /docs/operations/healthchecks.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Health Checks 6 | 7 | ## Recommended Components 8 | 9 | We don't recommend the use of a module to add health checks to your application. It's 10 | best to stick with a minimal implementation for most cases. The tradeoff between the amount 11 | of code you need to add to your application for a minimal implementation versus 12 | the costs of adding a new dependency leads us to recommend adding the code directly. 13 | Examples of how to add this code to your application are provided in the Guidance section. 14 | 15 | ## Guidance 16 | 17 | Kubernetes includes built in liveness and readiness monitoring and document 18 | requirements for these endpoints. We recommended following the 19 | kubernetes requirements as they are well defined, broadly used, and make 20 | your application ready for Kubernetes deployment even if you initially use 21 | something else. 22 | 23 | [Kubernetes liveness and readiness probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) offer three different options: Probe type, port and response as described in the 24 | sections which follow. 25 | 26 | ### Probe type 27 | 28 | We recommend using an HTTP probe type (`httpGet`). It demonstrates that the HTTP 29 | server is up and responding to requests and is the most commonly used probe 30 | type for services that expose HTTP as part of their function. 31 | 32 | When using a Service Mesh (Istio), there are are potential 33 | issues that you need to address. If you have mutual TLS enabled, 34 | using `httpGet` probes with Istio requires some specific configuration. Check the Istio 35 | [guide](https://istio.io/docs/ops/configuration/mesh/app-health-check/) to see 36 | the options available when using HTTP request. If this configuration is 37 | not practical for your deployment then TCP probes provide less coverage but 38 | are simpler to support. 39 | 40 | ### Port 41 | 42 | We recommend responding to probes from the same port as the application server. 43 | Its simple, common, and demonstrates that the HTTP server is up and responding 44 | to requests. 45 | 46 | By listening on the same port, it makes it easy to be certain that the container 47 | does not start responding to probes until it is ready to respond with 48 | application traffic. 49 | 50 | ### Response 51 | 52 | The response does not need to return any data, but status must be `200/OK`. For 53 | humans, it may be useful to return a minimal response body, such as `ok`. 54 | 55 | It may be tempting (particularly based on 56 | tutorials available on the web) to do additional internal state checks 57 | or checks on the availability of dependencies. 58 | 59 | For liveness probes in particular 60 | this can often do more harm than good as the end result is the container 61 | being restarted. For example, if a database used by the application is 62 | down, restarting the container in which the Node.js application using that 63 | database runs, is unlikely to help and can hurt but adding the additional 64 | load of continuously restarting containers. 65 | 66 | For readiness probes, there are advanced use cases where it makes sense 67 | for the service to modify its probe states to 68 | participate in container orchestration. For example, stopping responding on 69 | /readyz and allowing active connections to drain on the main port. When these 70 | requirements exist it makes sense to implement a more complete readiness 71 | endpoint. In other cases it is better to stick to the 72 | simple implementation. For example, in the case of a database that is 73 | down, it is better to respond indicating there is a problem with the database 74 | versus failing the readiness check as that results in the loss of the 75 | ability to provided 5xx responses to requests so that the client 76 | knows what's wrong. 77 | 78 | ### Endpoints 79 | 80 | We recommend that you use consistent naming for your endpoints across micro-services. `/readyz` and `/livez` are common choices for the endpoints for the readiness and 81 | liveness probes, respectively. 82 | 83 | Any route name can work if it agrees with the probe configuration, but in the 84 | absence of some requirement by the tooling, best to use names that have a 85 | clear relationship to their purpose. `/healthz` is not clear as to whether it is 86 | liveness or readiness. Because 87 | [the differences between them are important](https://developers.redhat.com/blog/2020/11/10/you-probably-need-liveness-and-readiness-probes), 88 | it's best to clarify. 89 | 90 | The "z" at the end of `/readyz` and `/livez` are a pattern called "z pages" that 91 | is a pattern used by [internal Kubernetes services](https://kubernetes.io/docs/reference/using-api/health-checks/) and has also been adopted by some other projects like [OpenCensus](https://opencensus.io/zpages/). 92 | 93 | ### Frequency of checking 94 | 95 | Since probe states shouldn't change once the application is serving traffic, 96 | there is no need for aggressive probe periods. The initial delay for the liveness 97 | probe should be ample enough for application startup. If its too short, 98 | Kubernetes will keep terminating the container before it serves traffic. Since 99 | the only typical reason to not respond to a readiness probe once the application 100 | is up is that the application is exiting on container termination, Kubernetes 101 | will already know that the container is terminating. Excessively frequent 102 | checking here can also be counter productive. 103 | 104 | We recommend that you don't specify specific values for your application and 105 | use the cluster defaults unless your application needs more time to 106 | startup (readiness) or to respond to liveness checks when under load. 107 | 108 | ### Example code and configuration 109 | 110 | It is easy to add simple endpoints with with pure Express.js, 111 | or your framework of choice. For example with Express: 112 | 113 | ```javascript 114 | const app = require("express")(); 115 | 116 | // Note that when collecting metrics, the management endpoints should be 117 | // implemented before the instrumentation that collects metrics, so that 118 | // these endpoints are not counted in the metrics. 119 | app.get("/readyz", (req, res) => res.status(200).json({ status: "ok" })); 120 | app.get("/livez", (req, res) => res.status(200).json({ status: "ok" })); 121 | 122 | // ... rest of app... 123 | 124 | app.listen(); 125 | ``` 126 | 127 | The kubernetes endpoints exposed by the application have to agree with the probe configuration: 128 | 129 | ```yaml 130 | readinessProbe: 131 | httpGet: 132 | path: /readyz 133 | port: 3000 134 | livenessProbe: 135 | httpGet: 136 | path: /livez 137 | port: 3000 138 | ``` 139 | -------------------------------------------------------------------------------- /docs/operations/logging.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Logging 6 | 7 | ## Recommended Components 8 | 9 | - Pino - http://getpino.io/#/ 10 | 11 | Pino provides an easily consumed API, structured logging and good performance 12 | which makes it well suited to cloud native deployments were more complicated 13 | APIs/features are not required as log output is simply written to standard out 14 | It has a respective level of weekly npm downloads (495k as of Nov 2019) 15 | and is growing. It was inspired by Bunyan which no longer seems to be maintained 16 | and is a good migration option. 17 | 18 | # Guidance 19 | 20 | Pino http://getpino.io/#/ is the recommended log framework for Node.js due 21 | to its easily consumed API, structured json logging by default 22 | and good performance. 23 | 24 | When deploying Pino we have the following additional recommendations: 25 | 26 | - Send logs to standard out and use log aggregation tools to collect 27 | logs across processes, containers and applications. All log processing 28 | should be done in a separate process. 29 | - Plan for a final resting place for log data. After 7 days migrate 30 | log data to a lower cost storage (manual retrieval is likely ok). 31 | - Add code to your application in order to allow logger.level 32 | to be set through an Environment variable so that can be easily 33 | changed in container environments. 34 | - Use the [redaction](https://github.com/pinojs/pino/blob/HEAD/docs/redaction.md) 35 | option to ensure sensitive data is not logged. Do note that this implementation 36 | does not allow one to dynamically add fields to be redacted [1](#footnote1). 37 | - Limit the use of warn, error, and fatal levels to information 38 | which must always be logged. 39 | - Limit the use of info level to important information which can 40 | always be logged without introducing significant overhead. 41 | - Don't throw and catch multiple errors, throw once and catch/log at the 42 | highest level, 43 | - When catching errors at a high level, log the error.stack unless the thrown error 44 | type is known and expected. 45 | - Every source file should utilize Pino's child method off of the common logger 46 | instance, passing in { file: module } to make the source file path is part of 47 | the log. 48 | 49 | ### Footnotes: 50 | 51 | 1: If you require ability to dynamically append what is 52 | redacted (like values read from a secret-storage like Vault), one can implement 53 | redacting logic inside a Pino 54 | [logMethod](https://getpino.io/#/docs/api?id=logmethod) to filter the message 55 | string and objects. 56 | 57 | ## Further Reading 58 | 59 | [Introduction to the Node.js reference architecture: Logging](https://developer.ibm.com/blogs/nodejs-reference-architectire-pino-for-logging) 60 | -------------------------------------------------------------------------------- /docs/operations/metrics.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Metrics 6 | 7 | ## Recommended packages 8 | 9 | - [prom-client](https://www.npmjs.com/package/prom-client). With >300k weekly downloads 10 | prom-client is both the most used and most flexible Prometheus client. It also has 11 | a shallow dependency tree. 12 | 13 | - [express-prom-bundle](https://www.npmjs.com/package/express-prom-bundle), version 5 14 | or later. It is based on prom-client and if you are using the Express web 15 | framework this is a good way to export Prometheus metrics. It's more succinct 16 | to use to get started, but also more opinionated. Its a reasonable option 17 | until/unless more control or custom metrics are needed. 18 | 19 | ## Guidance 20 | 21 | - Export Prometheus endpoints for containers running Node.js applications. Without 22 | these end points it can be difficult monitor your applications. Prometheus is 23 | the defacto standard for exposing metrics in Cloud Native applications. Further 24 | Cloud Native infrastructure (Kubernetes distributions) make it easily to collect 25 | Prometheus metrics and it is also easy to collect and graph even if you need 26 | to install the infrastructure components. 27 | 28 | - Collect and monitor "RED" metrics. Details are available in 29 | 30 | - https://medium.com/faun/how-to-monitor-the-sre-golden-signals-1391cadc7524 31 | - https://www.weave.works/blog/the-red-method-key-metrics-for-microservices-architecture/ 32 | 33 | - For HTTP expose the `RED` metrics as: 34 | 35 | - request rate - requests which are handled ok (status code==2xx). Expose this as the total 36 | count. 37 | - error rate - requests which are not handled ok ( status code!=2xx). Expose this metric 38 | as a percentage of the total rate. 39 | - request latency - duration of requests which are handled ok, grouped into ranges/buckets and 40 | exposed through a Prometheus histogram. 41 | 42 | - [prometheus-nodejs-tutorial](https://github.com/csantanapr/prometheus-nodejs-tutorial) provides 43 | examples of using prom-client and express-prom-bundle to collect metrics. Lab 3 and 6 44 | show how to generate the http_request_duration_seconds_bucket metric. 45 | 46 | Configure Prometheus middleware as the first middleware to start the timer as soon as possible. 47 | When setting up the middleware define your expose route for metrics `/metrics` before activating the middleware 48 | to avoid calls to `/metrics` to be counted as part of the metrics, you can do the same for 49 | liveness and readiness checks to define them before Prometheus middleware if you want to discard them from your 50 | http metrics calculations. 51 | 52 | For success rate the Prometheus query would be 53 | `sum(rate(http_request_duration_seconds_count{code="2xx", app="myapp"}[5m]))`. 54 | The sum over all instances, the rate of change of the request count for app 55 | my app with status_code 2xx over a 5m window 56 | 57 | For error rate, but the status_code is usually 4xx or 5xx expressed as [45]xx. The 58 | Prometheus query would be `sum(rate(http_request_duration_seconds_count{code="[45]xx", app="myapp"}[5m]))`. 59 | 60 | For duration, or latency the metric is a histogram so you will graph and 61 | monitor percentiles instead of a summary. For example, the Prometheus query would be 62 | to get the 95 percentile over all instances over 5m window would be 63 | `histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket{code="2xx", app="myapp"}[5m]))` 64 | 65 | - Export additional custom metrics to provide key attributes about the operation of 66 | your application which are not part of the standard metrics. 67 | 68 | - Be aware that the Prometheus client instance needs to be a singleton within your app. For example, if your 69 | application imports separate packages that utilize the "prom-client" package, like customized RabbitMQ & 70 | Redis drivers that write metrics to prom-client, you need to make sure they use the same prom-client instance. 71 | A common way to do that is to make the prom-client instance as an optional parameter in the constructor for 72 | those drivers, and then your app can pass in the same prom-client instance into both. 73 | -------------------------------------------------------------------------------- /npcheck-review/npcheck-April7-2025.md: -------------------------------------------------------------------------------- 1 | # npcheck review - April 07 2025 2 | 3 | 4 | 5 | ## Diff in npcheck.json since last review 6 | 7 | ```shell 8 | ``` 9 | 10 | ## Results 11 | 12 | https://github.com/nodeshift/nodejs-reference-architecture/actions/runs/12970009285/job/36174752220 13 | 14 | 15 | NPCheck Report 16 | 17 | ```shell 18 | NPCheck Report 19 | (1): The module "node-rdkafka" seems to have no available TypeScript typings. 20 | (2): The "cldr-localenames-full" seems that is lacking appropriate testing (https://www.github.com/unicode-cldr/cldr-json) 21 | (3): The module "cldr-localenames-full" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 22 | (4): The module "cldr-localenames-full" seems to have no available TypeScript typings. 23 | (5): The module "eslint" has "83" dependencies (including sub-dependencies) which is more than the default "20". 24 | (6): The module "express" seems to have no available TypeScript typings. 25 | (7): The module "express" has "65" dependencies (including sub-dependencies) which is more than the default "20". 26 | (8): The latest release of "ibmcloud-appid" was about 2 years ago 27 | (9): The module "ibmcloud-appid" has "230" dependencies (including sub-dependencies) which is more than the default "20". 28 | (10): The module "i18next" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 29 | (11): The module "i18next" is not tested by community CITGM runs. 30 | (12): The latest release of "i18next-icu" was about 2 years ago 31 | (13): The module "i18next-icu" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 32 | (14): The module "i18next-http-middleware" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 33 | (15): The module "i18next-fs-backend" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 34 | (16): The module "ioredis" is not tested by community CITGM runs. 35 | (17): The module "opossum" seems to have no available TypeScript typings. 36 | (18): The latest release of "passport" was over 1 year ago 37 | (19): The module "passport" seems to have no available TypeScript typings. 38 | (20): The module "pino" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 39 | (21): The latest release of "prom-client" was 9 months ago 40 | (22): The module "rhea" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 41 | (23): The module "lru-cache" has no support for the LTS version(s) 18.20.8 of Node.js. 42 | (24): The module "mocha" seems to have no available TypeScript typings. 43 | (25): The module "mocha" has "83" dependencies (including sub-dependencies) which is more than the default "20". 44 | (26): The "jest" seems that is lacking appropriate testing (https://www.github.com/jestjs/jest) 45 | (27): The module "jest" has "257" dependencies (including sub-dependencies) which is more than the default "20". 46 | (28): The module "@ibm-cloud/cloudant" has "58" dependencies (including sub-dependencies) which is more than the default "20". 47 | (29): The latest release of "nano" was 8 months ago 48 | (30): The module "nano" has "31" dependencies (including sub-dependencies) which is more than the default "20". 49 | (31): The module "@elastic/elasticsearch" has "31" dependencies (including sub-dependencies) which is more than the default "20". 50 | (32): The latest release of "odbc" was 8 months ago 51 | (33): The module "odbc" has "56" dependencies (including sub-dependencies) which is more than the default "20". 52 | (34): The module "ibm_db" seems to have no available TypeScript typings. 53 | (35): The module "ibm_db" has "59" dependencies (including sub-dependencies) which is more than the default "20". 54 | (36): The module "mongodb" is not tested by community CITGM runs. 55 | (37): The module "pg" seems to have no available TypeScript typings. 56 | (38): The module "pg" is not tested by community CITGM runs. 57 | (39): The latest release of "kafkajs" was about 2 years ago 58 | (40): The "@openapitools/openapi-generator-cli" seems that is lacking appropriate testing (https://www.github.com/OpenAPITools/openapi-generator-cli) 59 | (41): The module "@openapitools/openapi-generator-cli" seems to have no available TypeScript typings. 60 | (42): The module "@openapitools/openapi-generator-cli" has "145" dependencies (including sub-dependencies) which is more than the default "20". 61 | (43): The module "openapi-backend" has "38" dependencies (including sub-dependencies) which is more than the default "20". 62 | (44): The module "@stoplight/prism-cli" is not tested by community CITGM runs. 63 | (45): The module "@stoplight/prism-cli" has "178" dependencies (including sub-dependencies) which is more than the default "20". 64 | (46): The module "express-openapi-validator" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 65 | (47): The module "express-openapi-validator" has "111" dependencies (including sub-dependencies) which is more than the default "20". 66 | (48): The module "swagger-editor" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 67 | (49): The module "swagger-editor" seems to have no available TypeScript typings. 68 | (50): The module "swagger-editor" has "377" dependencies (including sub-dependencies) which is more than the default "20". 69 | (51): The latest release of "openapi-editor" was over 4 years ago 70 | (52): The module "openapi-editor" has "191" dependencies (including sub-dependencies) which is more than the default "20". 71 | (53): The latest release of "nyc" was 7 months ago 72 | (54): The module "nyc" seems to have no available TypeScript typings. 73 | (55): The module "nyc" is not tested by community CITGM runs. 74 | (56): The module "nyc" has "136" dependencies (including sub-dependencies) which is more than the default "20". 75 | (57): The module "dotenv" is not tested by community CITGM runs. 76 | (58): The latest release of "node-vault" was over 1 year ago 77 | (59): The module "node-vault" seems to have no available TypeScript typings. 78 | (60): The module "node-vault" is not tested by community CITGM runs. 79 | (61): The module "node-vault" has "49" dependencies (including sub-dependencies) which is more than the default "20". 80 | (62): The module "@ibm-cloud/secrets-manager" seems to have no available TypeScript typings. 81 | (63): The module "@ibm-cloud/secrets-manager" is not tested by community CITGM runs. 82 | (64): The module "@ibm-cloud/secrets-manager" has "58" dependencies (including sub-dependencies) which is more than the default "20". 83 | (65): The module "@opentelemetry/sdk-trace-base" is not tested by community CITGM runs. 84 | (66): The module "@opentelemetry/sdk-trace-node" is not tested by community CITGM runs. 85 | (67): The module "axios" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 86 | (68): The module "axios" is not tested by community CITGM runs. 87 | (69): The module "axios" has "22" dependencies (including sub-dependencies) which is more than the default "20". 88 | (70): The latest release of "node-fetch" was over 1 year ago 89 | (71): The module "node-fetch" is not tested by community CITGM runs. 90 | (72): The latest release of "cors" was over 6 years ago 91 | (73): The module "cors" seems to have no available TypeScript typings. 92 | (74): The module "cors" is not tested by community CITGM runs. 93 | 94 | problems: 74 (errors: 0 - warnings: 74) 95 | ``` 96 | 97 | 98 | New (materially) since last review (excluding ones were # deps was already over limit and changed): 99 | ``` 100 | None 101 | ``` 102 | ## Notes 103 | 104 | Since the last report Axios has increased its dependencies to 22 105 | 106 | A few modules are `aging` in terms of the last release. Not necessariliy something to worry about yet but worth keeping an eye on 107 | 108 | Aging 109 | 110 | The latest release of "nano" was 8 months ago 111 | The latest release of "odbc" was 8 months ago 112 | The latest release of "nyc" was 7 months ago 113 | 114 | -------------------------------------------------------------------------------- /npcheck-review/npcheck-jan9-2024.md: -------------------------------------------------------------------------------- 1 | # npcheck review - Jan 9 2023 2 | 3 | No major concerns were noted in this review. 4 | 5 | ## Diff in npcheck.json since last review 6 | 7 | None 8 | 9 | ## Results 10 | 11 | run locally due to automation issues 12 | 13 | npcheck report 14 | 15 | ```shell 16 | 1): The "cldr-localenames-full" seems that is lacking appropriate testing (https://www.github.com/unicode-cldr/cldr-json) 17 | (2): The module "cldr-localenames-full" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 18 | (3): The module "cldr-localenames-full" seems to have no available TypeScript typings. 19 | (4): The module "eslint" seems to have no available TypeScript typings. 20 | (5): The module "eslint" has "98" dependencies (including sub-dependencies) which is more than the default "20". 21 | (6): The latest release of "express" was over 1 year ago 22 | (7): The module "express" seems to have no available TypeScript typings. 23 | (8): The module "express" is not tested by community CITGM runs. 24 | (9): The module "express" has "60" dependencies (including sub-dependencies) which is more than the default "20". 25 | (10): The module "express-prom-bundle" has "78" dependencies (including sub-dependencies) which is more than the default "20". 26 | (11): The latest release of "ibmcloud-appid" was 11 months ago 27 | (12): The module "ibmcloud-appid" has "224" dependencies (including sub-dependencies) which is more than the default "20". 28 | (13): The module "i18next" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 29 | (14): The module "i18next" is not tested by community CITGM runs. 30 | (15): The latest release of "i18next-icu" was 9 months ago 31 | (16): The module "i18next-icu" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 32 | (17): The module "i18next-http-middleware" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 33 | (18): The module "i18next-fs-backend" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 34 | (19): The latest release of "ioredis" was 9 months ago 35 | (20): The module "ioredis" is not tested by community CITGM runs. 36 | (21): The module "node-rdkafka" seems to have no available TypeScript typings. 37 | (22): The module "opossum" seems to have no available TypeScript typings. 38 | (23): The module "passport" seems to have no available TypeScript typings. 39 | (24): The module "pino" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 40 | (25): The module "pino" has "22" dependencies (including sub-dependencies) which is more than the default "20". 41 | (26): The latest release of "rhea" was 12 months ago 42 | (27): The module "rhea" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 43 | (28): The latest release of "mocha" was about 1 year ago 44 | (29): The module "mocha" seems to have no available TypeScript typings. 45 | (30): The module "mocha" has "72" dependencies (including sub-dependencies) which is more than the default "20". 46 | (31): The "jest" seems that is lacking appropriate testing (https://www.github.com/jestjs/jest) 47 | (32): The module "jest" has "261" dependencies (including sub-dependencies) which is more than the default "20". 48 | (33): The module "@ibm-cloud/cloudant" has "96" dependencies (including sub-dependencies) which is more than the default "20". 49 | (34): The module "nano" has "23" dependencies (including sub-dependencies) which is more than the default "20". 50 | (35): The latest release of "odbc" was 8 months ago 51 | (36): The module "odbc" has "57" dependencies (including sub-dependencies) which is more than the default "20". 52 | (37): The module "ibm_db" seems to have no available TypeScript typings. 53 | (38): The module "ibm_db" has "45" dependencies (including sub-dependencies) which is more than the default "20". 54 | (39): The module "mongodb" is not tested by community CITGM runs. 55 | (40): The module "pg" seems to have no available TypeScript typings. 56 | (41): The module "pg" is not tested by community CITGM runs. 57 | (42): The latest release of "kafkajs" was 11 months ago 58 | (43): The "@openapitools/openapi-generator-cli" seems that is lacking appropriate testing (https://www.github.com/OpenAPITools/openapi-generator-cli) 59 | (44): The module "@openapitools/openapi-generator-cli" seems to have no available TypeScript typings. 60 | (45): The module "@openapitools/openapi-generator-cli" has "106" dependencies (including sub-dependencies) which is more than the default "20". 61 | (46): The module "openapi-backend" has "36" dependencies (including sub-dependencies) which is more than the default "20". 62 | (47): The module "@stoplight/prism-cli" is not tested by community CITGM runs. 63 | (48): The module "@stoplight/prism-cli" has "179" dependencies (including sub-dependencies) which is more than the default "20". 64 | (49): The module "express-openapi-validator" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 65 | (50): The module "express-openapi-validator" has "57" dependencies (including sub-dependencies) which is more than the default "20". 66 | (51): The module "swagger-editor" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 67 | (52): The module "swagger-editor" seems to have no available TypeScript typings. 68 | (53): The module "swagger-editor" has "330" dependencies (including sub-dependencies) which is more than the default "20". 69 | (54): The latest release of "openapi-editor" was about 3 years ago 70 | (55): The module "openapi-editor" has "200" dependencies (including sub-dependencies) which is more than the default "20". 71 | (56): The latest release of "nyc" was over 3 years ago 72 | (57): The module "nyc" seems to have no available TypeScript typings. 73 | (58): The module "nyc" is not tested by community CITGM runs. 74 | (59): The module "nyc" has "145" dependencies (including sub-dependencies) which is more than the default "20". 75 | (60): The latest release of "dotenv" was 7 months ago 76 | (61): The module "dotenv" is not tested by community CITGM runs. 77 | (62): The module "node-vault" seems to have no available TypeScript typings. 78 | (63): The module "node-vault" is not tested by community CITGM runs. 79 | (64): The module "node-vault" has "59" dependencies (including sub-dependencies) which is more than the default "20". 80 | (65): The module "@ibm-cloud/secrets-manager" seems to have no available TypeScript typings. 81 | (66): The module "@ibm-cloud/secrets-manager" is not tested by community CITGM runs. 82 | (67): The module "@ibm-cloud/secrets-manager" has "95" dependencies (including sub-dependencies) which is more than the default "20". 83 | (68): The module "@opentelemetry/sdk-trace-base" is not tested by community CITGM runs. 84 | (69): The module "@opentelemetry/sdk-trace-node" is not tested by community CITGM runs. 85 | (70): The module "axios" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 86 | (71): The module "axios" is not tested by community CITGM runs. 87 | (72): The module "node-fetch" is not tested by community CITGM runs. 88 | (73): The latest release of "cors" was about 5 years ago 89 | (74): The module "cors" seems to have no available TypeScript typings. 90 | (75): The module "cors" is not tested by community CITGM runs. 91 | ``` 92 | 93 | New (materially) since last review (excluding ones were # deps was already over limit and changed): 94 | ``` 95 | (10): The module "express-prom-bundle" has "78" dependencies (including sub-dependencies) which is more than the default "20". 96 | (19): The latest release of "ioredis" was 9 months ago 97 | (35): The latest release of "odbc" was 8 months ago 98 | (60): The latest release of "dotenv" was 7 months ago 99 | ``` 100 | ## Notes 101 | - the increase in deps in express-prom-bundle is noted but not a reason to drop from ref arch 102 | - the increased times since a release of ioredis, odbc and dotenv is noted, will continue to see if time since last release 103 | continues to strech out. 104 | 105 | -------------------------------------------------------------------------------- /npcheck-review/npcheck-january29-2025.md: -------------------------------------------------------------------------------- 1 | # npcheck review - January 29 2025 2 | 3 | 4 | 5 | ## Diff in npcheck.json since last review 6 | 7 | ```shell 8 | ``` 9 | 10 | ## Results 11 | 12 | https://github.com/nodeshift/nodejs-reference-architecture/actions/runs/12970009285/job/36174752220 13 | 14 | 15 | NPCheck Report 16 | 17 | ```shell 18 | NPCheck Report 19 | (1): The module "node-rdkafka" seems to have no available TypeScript typings. 20 | (2): The "cldr-localenames-full" seems that is lacking appropriate testing (https://www.github.com/unicode-cldr/cldr-json) 21 | (3): The module "cldr-localenames-full" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 22 | (4): The module "cldr-localenames-full" seems to have no available TypeScript typings. 23 | (5): The module "eslint" has "82" dependencies (including sub-dependencies) which is more than the default "20". 24 | (6): The module "express" seems to have no available TypeScript typings. 25 | (7): The module "express" has "66" dependencies (including sub-dependencies) which is more than the default "20". 26 | (8): The latest release of "ibmcloud-appid" was almost 2 years ago 27 | (9): The module "ibmcloud-appid" has "228" dependencies (including sub-dependencies) which is more than the default "20". 28 | (10): The module "i18next" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 29 | (11): The module "i18next" is not tested by community CITGM runs. 30 | (12): The latest release of "i18next-icu" was almost 2 years ago 31 | (13): The module "i18next-icu" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 32 | (14): The module "i18next-http-middleware" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 33 | (15): The module "i18next-fs-backend" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 34 | (16): The module "ioredis" is not tested by community CITGM runs. 35 | (17): The module "opossum" seems to have no available TypeScript typings. 36 | (18): The latest release of "passport" was about 1 year ago 37 | (19): The module "passport" seems to have no available TypeScript typings. 38 | (20): The module "pino" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 39 | (21): The latest release of "prom-client" was 7 months ago 40 | (22): The module "rhea" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 41 | (23): The module "lru-cache" has no support for the LTS version(s) 18.20.6 of Node.js. 42 | (24): The module "mocha" seems to have no available TypeScript typings. 43 | (25): The module "mocha" has "83" dependencies (including sub-dependencies) which is more than the default "20". 44 | (26): The "jest" seems that is lacking appropriate testing (https://www.github.com/jestjs/jest) 45 | (27): The module "jest" has "257" dependencies (including sub-dependencies) which is more than the default "20". 46 | (28): The module "@ibm-cloud/cloudant" has "54" dependencies (including sub-dependencies) which is more than the default "20". 47 | (29): The module "nano" has "29" dependencies (including sub-dependencies) which is more than the default "20". 48 | (30): The module "@elastic/elasticsearch" has "31" dependencies (including sub-dependencies) which is more than the default "20". 49 | (31): The module "odbc" has "56" dependencies (including sub-dependencies) which is more than the default "20". 50 | (32): The module "ibm_db" seems to have no available TypeScript typings. 51 | (33): The module "ibm_db" has "45" dependencies (including sub-dependencies) which is more than the default "20". 52 | (34): The module "mongodb" is not tested by community CITGM runs. 53 | (35): The module "pg" seems to have no available TypeScript typings. 54 | (36): The module "pg" is not tested by community CITGM runs. 55 | (37): The latest release of "kafkajs" was almost 2 years ago 56 | (38): The "@openapitools/openapi-generator-cli" seems that is lacking appropriate testing (https://www.github.com/OpenAPITools/openapi-generator-cli) 57 | (39): The module "@openapitools/openapi-generator-cli" seems to have no available TypeScript typings. 58 | (40): The module "@openapitools/openapi-generator-cli" has "131" dependencies (including sub-dependencies) which is more than the default "20". 59 | (41): The module "openapi-backend" has "38" dependencies (including sub-dependencies) which is more than the default "20". 60 | (42): The module "@stoplight/prism-cli" is not tested by community CITGM runs. 61 | (43): The module "@stoplight/prism-cli" has "178" dependencies (including sub-dependencies) which is more than the default "20". 62 | (44): The module "express-openapi-validator" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 63 | (45): The module "express-openapi-validator" has "112" dependencies (including sub-dependencies) which is more than the default "20". 64 | (46): The module "swagger-editor" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 65 | (47): The module "swagger-editor" seems to have no available TypeScript typings. 66 | (48): The module "swagger-editor" has "375" dependencies (including sub-dependencies) which is more than the default "20". 67 | (49): The latest release of "openapi-editor" was about 4 years ago 68 | (50): The module "openapi-editor" has "191" dependencies (including sub-dependencies) which is more than the default "20". 69 | (51): The module "nyc" seems to have no available TypeScript typings. 70 | (52): The module "nyc" is not tested by community CITGM runs. 71 | (53): The module "nyc" has "136" dependencies (including sub-dependencies) which is more than the default "20". 72 | (54): The module "dotenv" is not tested by community CITGM runs. 73 | (55): The latest release of "node-vault" was over 1 year ago 74 | (56): The module "node-vault" seems to have no available TypeScript typings. 75 | (57): The module "node-vault" is not tested by community CITGM runs. 76 | (58): The module "node-vault" has "59" dependencies (including sub-dependencies) which is more than the default "20". 77 | (59): The module "@ibm-cloud/secrets-manager" seems to have no available TypeScript typings. 78 | (60): The module "@ibm-cloud/secrets-manager" is not tested by community CITGM runs. 79 | (61): The module "@ibm-cloud/secrets-manager" has "53" dependencies (including sub-dependencies) which is more than the default "20". 80 | (62): The module "@opentelemetry/sdk-trace-base" is not tested by community CITGM runs. 81 | (63): The module "@opentelemetry/sdk-trace-node" is not tested by community CITGM runs. 82 | (64): The module "axios" does not specify the engines field or package-support.json, so we cannot determine if it supports the LTS versions of Node.js. 83 | (65): The module "axios" is not tested by community CITGM runs. 84 | (66): The latest release of "node-fetch" was over 1 year ago 85 | (67): The module "node-fetch" is not tested by community CITGM runs. 86 | (68): The latest release of "cors" was about 6 years ago 87 | (69): The module "cors" seems to have no available TypeScript typings. 88 | (70): The module "cors" is not tested by community CITGM runs. 89 | 90 | problems: 70 (errors: 0 - warnings: 70) 91 | ``` 92 | 93 | 94 | New (materially) since last review (excluding ones were # deps was already over limit and changed): 95 | ``` 96 | None 97 | ``` 98 | ## Notes 99 | 100 | There was a release of express-prom-bundle since the last report. It had been 9 months since the last one 101 | 102 | There was a release of dotenv since the last report. It had been 8 months since the last one 103 | 104 | 105 | A few modules are `aging` in terms of the last release. Not necessariliy something to worry about yet but worth keeping an eye on 106 | 107 | Aging 108 | 109 | The latest release of "passport" was 11 months ago 110 | The latest release of "node-vault" was about 1 year ago 111 | The latest release of "node-fetch" was about 1 year ago 112 | 113 | -------------------------------------------------------------------------------- /npcheck-review/npcheck-july22-2021.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # npcheck review - July 22 - 2021 4 | 5 | ## Results 6 | 7 | ```shell 8 | (1): The "cldr-localenames-full" seems that is lacking appropriate testing (https://www.github.com/unicode-cldr/cldr-json) 9 | 10 | (2): The module "cldr-localenames-full" appears to have no support for the LTS version(s) 12.22.3, 14.17.3 of Node.js. 11 | 12 | (3): The latest release of "express" was over 1 year ago 13 | 14 | (4): The latest release of "ibmcloud-appid" was 12 months ago 15 | 16 | (5): The module "ibmcloud-appid" appears to have no support for the LTS version(s) 12.22.3, 14.17.3 of Node.js. 17 | 18 | (6): The module "i18next" appears to have no support for the LTS version(s) 12.22.3, 14.17.3 of Node.js. 19 | 20 | (7): The module "i18next-icu" appears to have no support for the LTS version(s) 12.22.3, 14.17.3 of Node.js. 21 | 22 | (8): The module "i18next-http-middleware" appears to have no support for the LTS version(s) 12.22.3, 14.17.3 of Node.js. 23 | 24 | (9): The module "i18next-fs-backend" appears to have no support for the LTS version(s) 12.22.3, 14.17.3 of Node.js. 25 | 26 | (10): The latest release of "node-rdkafka" was 6 months ago 27 | 28 | (11): The latest release of "passport" was over 1 year ago 29 | 30 | (12): The module "pino" appears to have no support for the LTS version(s) 12.22.3, 14.17.3 of Node.js. 31 | 32 | (13): The module "rhea" appears to have no support for the LTS version(s) 12.22.3, 14.17.3 of Node.js. 33 | 34 | (14): The latest release of "lru-cache" was about 1 year ago 35 | 36 | problems: 14 (errors: 0 - warnings: 14) 37 | ``` 38 | 39 | ## Notes 40 | 41 | * With respect to (10) Issues in terms of node-rdkafka have already been noted in the section on messings. 42 | * With respect to (4), (11), (14) we don't see a concern with those not having done a recent release. 43 | * With respect to (3) we are looking at web frameworks but the concensus is still the current recommendations 44 | * With respect to (1), after review it seems that being a data delivery package no testing is needed 45 | * With respect to the comments about "no support", those indicate that the package does not include 46 | an engines field or package-support.json file. We plan to update the message to indicate that we 47 | cannot tell autimatically if they support LTS versions. We have no reason to believe any of those 48 | flagged don't support the current LTS Node.js versions. 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs-reference-architecture", 3 | "version": "0.1.0", 4 | "description": "Reference architecture", 5 | "private": true, 6 | "main": "index.js", 7 | "directories": { 8 | "doc": "docs" 9 | }, 10 | "scripts": { 11 | "lint": "prettier ./README.md ./docs/**/*.md --write" 12 | }, 13 | "dependencies": { 14 | "prettier": "2.0.5" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/nodeshift/nodejs-reference-architecture.git" 19 | }, 20 | "author": "", 21 | "license": "ISC", 22 | "bugs": { 23 | "url": "https://github.com/nodeshift/nodejs-reference-architecture/issues" 24 | }, 25 | "homepage": "https://github.com/nodeshift/nodejs-reference-architecture#readme" 26 | } 27 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | 22 | docs/ 23 | -------------------------------------------------------------------------------- /website/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ``` 8 | $ yarn 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ``` 14 | $ yarn copyDocs 15 | $ yarn start 16 | ``` 17 | 18 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 19 | 20 | ### Build 21 | 22 | ``` 23 | $ yarn build 24 | ``` 25 | 26 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 27 | 28 | ### Deployment 29 | 30 | ``` 31 | $ GIT_USER= USE_SSH=true yarn deploy 32 | ``` 33 | if you are using SSH authentication otherwise 34 | 35 | ``` 36 | $ GIT_USER= USE_SSH=false yarn deploy 37 | ``` 38 | 39 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 40 | -------------------------------------------------------------------------------- /website/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /website/docusaurus.config.js: -------------------------------------------------------------------------------- 1 | const lightCodeTheme = require('prism-react-renderer/themes/github'); 2 | const darkCodeTheme = require('prism-react-renderer/themes/dracula'); 3 | 4 | // With JSDoc @type annotations, IDEs can provide config autocompletion 5 | /** @type {import('@docusaurus/types').DocusaurusConfig} */ 6 | (module.exports = { 7 | title: 'Node.JS Reference Architecture', 8 | tagline: 'Node.js Reference Architecture', 9 | url: 'https://nodeshift.dev', 10 | baseUrl: '/nodejs-reference-architecture/', 11 | onBrokenLinks: 'throw', 12 | onBrokenMarkdownLinks: 'warn', 13 | favicon: 'img/favicon.ico', 14 | organizationName: 'nodeshift', // Usually your GitHub org/user name. 15 | projectName: 'nodejs-reference-architecture', // Usually your repo name. 16 | 17 | presets: [ 18 | [ 19 | '@docusaurus/preset-classic', 20 | /** @type {import('@docusaurus/preset-classic').Options} */ 21 | ({ 22 | docs: { 23 | routeBasePath: '/', 24 | sidebarCollapsed: false, 25 | sidebarPath: require.resolve('./sidebars.js'), 26 | // Please change this to your repo. 27 | editUrl: 'https://github.com/nodeshift/nodejs-reference-architecture', 28 | } 29 | }), 30 | ], 31 | ], 32 | 33 | themeConfig: 34 | /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ 35 | ({ 36 | prism: { 37 | theme: darkCodeTheme, 38 | darkTheme: lightCodeTheme, 39 | }, 40 | }), 41 | }); 42 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "copyDocs": "cp -Rf ../docs ./docs", 8 | "start": "docusaurus start", 9 | "build": "docusaurus build", 10 | "swizzle": "docusaurus swizzle", 11 | "deploy": "docusaurus deploy", 12 | "clear": "docusaurus clear", 13 | "serve": "docusaurus serve", 14 | "write-translations": "docusaurus write-translations", 15 | "write-heading-ids": "docusaurus write-heading-ids" 16 | }, 17 | "dependencies": { 18 | "@docusaurus/core": "2.0.0-beta.6", 19 | "@docusaurus/preset-classic": "2.0.0-beta.6", 20 | "@mdx-js/react": "^1.6.21", 21 | "@svgr/webpack": "^5.5.0", 22 | "clsx": "^1.1.1", 23 | "file-loader": "^6.2.0", 24 | "prism-react-renderer": "^1.2.1", 25 | "react": "^17.0.1", 26 | "react-dom": "^17.0.1", 27 | "url-loader": "^4.1.1" 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.5%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 1 chrome version", 37 | "last 1 firefox version", 38 | "last 1 safari version" 39 | ] 40 | } 41 | } -------------------------------------------------------------------------------- /website/sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | module.exports = { 13 | // By default, Docusaurus generates a sidebar from the docs folder structure 14 | tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], 15 | 16 | // But you can create a sidebar manually 17 | /* 18 | tutorialSidebar: [ 19 | { 20 | type: 'category', 21 | label: 'Tutorial', 22 | items: ['hello'], 23 | }, 24 | ], 25 | */ 26 | }; 27 | -------------------------------------------------------------------------------- /website/src/pages/index.js_disabled: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Layout from '@theme/Layout'; 3 | import Link from '@docusaurus/Link'; 4 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; 5 | 6 | export default function Home() { 7 | const {siteConfig} = useDocusaurusContext(); 8 | return ( 9 | 12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /website/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodeshift/nodejs-reference-architecture/37ed5147abc16cd7ddcda1a321fc348d1f51c619/website/static/.nojekyll -------------------------------------------------------------------------------- /website/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodeshift/nodejs-reference-architecture/37ed5147abc16cd7ddcda1a321fc348d1f51c619/website/static/favicon.ico -------------------------------------------------------------------------------- /website/static/img/docusaurus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nodeshift/nodejs-reference-architecture/37ed5147abc16cd7ddcda1a321fc348d1f51c619/website/static/img/docusaurus.png -------------------------------------------------------------------------------- /website/static/img/logo.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------