Run prettier

pull/3734/head
Kamran Ahmed 2 years ago
parent d081ecf5b3
commit 7434ff71eb
  1. 7
      .prettierignore
  2. 2
      astro.config.mjs
  3. 31
      bin/best-practice-dirs.cjs
  4. 3
      bin/readme.md
  5. 9
      bin/roadmap-content.cjs
  6. 5
      bin/roadmap-dirs.cjs
  7. 27
      bin/update-sponsors.cjs
  8. 20
      code_of_conduct.md
  9. 1
      package.json
  10. 2
      playwright.config.ts
  11. 3876
      pnpm-lock.yaml
  12. 14
      sitemap.mjs
  13. 55
      src/components/TopicOverlay/topic.js
  14. 47
      src/data/best-practices/api-security/api-security.md
  15. 2
      src/data/best-practices/api-security/content/endpoint-authentication.md
  16. 2
      src/data/best-practices/api-security/content/proper-http-methods.md
  17. 1
      src/data/best-practices/api-security/content/proper-response-code.md
  18. 1
      src/data/best-practices/api-security/content/restrict-private-apis.md
  19. 1
      src/data/best-practices/api-security/content/use-https.md
  20. 1
      src/data/best-practices/api-security/content/validate-content-type.md
  21. 1
      src/data/best-practices/aws/content/pre-warm-elb.md
  22. 2
      src/data/best-practices/aws/content/security-audit.md
  23. 1
      src/data/best-practices/aws/content/use-iam-acount.md
  24. 1
      src/data/best-practices/frontend-performance/content/keep-dependencies-up-to-date.md
  25. 1
      src/data/best-practices/frontend-performance/content/minify-html.md
  26. 1
      src/data/best-practices/frontend-performance/content/page-load-time-below-3s.md
  27. 166
      src/data/best-practices/frontend-performance/content/recommended-guides.md
  28. 1
      src/data/best-practices/frontend-performance/content/use-non-blocking-javascript.md
  29. 2
      src/data/best-practices/frontend-performance/content/use-preconnect-to-load-fonts.md
  30. 36
      src/data/best-practices/frontend-performance/frontend-performance.md
  31. 25
      src/data/guides/asymptotic-notation.md
  32. 25
      src/data/guides/avoid-render-blocking-javascript-with-async-defer.md
  33. 25
      src/data/guides/basic-authentication.md
  34. 25
      src/data/guides/basics-of-authentication.md
  35. 25
      src/data/guides/big-o-notation.md
  36. 25
      src/data/guides/character-encodings.md
  37. 25
      src/data/guides/ci-cd.md
  38. 32
      src/data/guides/consistency-patterns-in-distributed-systems.md
  39. 294
      src/data/guides/design-patterns-for-humans.md
  40. 25
      src/data/guides/dhcp-in-one-picture.md
  41. 24
      src/data/guides/dns-in-one-picture.md
  42. 49
      src/data/guides/history-of-javascript.md
  43. 24
      src/data/guides/how-to-setup-a-jump-server.md
  44. 42
      src/data/guides/http-basic-authentication.md
  45. 48
      src/data/guides/http-caching.md
  46. 50
      src/data/guides/journey-to-http2.md
  47. 25
      src/data/guides/jwt-authentication.md
  48. 109
      src/data/guides/levels-of-seniority.md
  49. 25
      src/data/guides/oauth.md
  50. 41
      src/data/guides/proxy-servers.md
  51. 25
      src/data/guides/random-numbers.md
  52. 25
      src/data/guides/scaling-databases.md
  53. 25
      src/data/guides/session-authentication.md
  54. 78
      src/data/guides/session-based-authentication.md
  55. 20
      src/data/guides/setup-and-auto-renew-ssl-certificates.md
  56. 22
      src/data/guides/single-command-database-setup.md
  57. 25
      src/data/guides/ssl-tls-https-ssh.md
  58. 25
      src/data/guides/sso.md
  59. 25
      src/data/guides/token-authentication.md
  60. 72
      src/data/guides/torrent-client.md
  61. 25
      src/data/guides/unfamiliar-codebase.md
  62. 25
      src/data/guides/what-are-web-vitals.md
  63. 39
      src/data/guides/what-is-internet.md
  64. 25
      src/data/guides/what-is-sli-slo-sla.md
  65. 42
      src/data/guides/why-build-it-and-they-will-come-wont-work-anymore.md
  66. 136
      src/data/roadmaps/android/android.md
  67. 67
      src/data/roadmaps/angular/angular.md
  68. 1
      src/data/roadmaps/angular/content/100-typescript-basics/102-structural-typing.md
  69. 1
      src/data/roadmaps/angular/content/101-rxjs-basics/101-observable-lifecycle.md
  70. 2
      src/data/roadmaps/angular/content/101-rxjs-basics/104-operators/index.md
  71. 8
      src/data/roadmaps/angular/content/102-angular-basics/101-angular-components.md
  72. 1
      src/data/roadmaps/angular/content/103-angular-cli/102-ng-generate.md
  73. 1
      src/data/roadmaps/angular/content/103-angular-cli/103-ng-test.md
  74. 1
      src/data/roadmaps/angular/content/105-rendering-topics/100-builtin-directives.md
  75. 1
      src/data/roadmaps/angular/content/105-rendering-topics/101-builtin-pipes.md
  76. 1
      src/data/roadmaps/angular/content/108-services-remote-data/100-dependency-injection.md
  77. 1
      src/data/roadmaps/angular/content/110-state-management/100-ngxs.md
  78. 1
      src/data/roadmaps/angular/content/110-state-management/101-ngrx.md
  79. 93
      src/data/roadmaps/aspnet-core/aspnet-core.md
  80. 1
      src/data/roadmaps/aspnet-core/content/102-database-fundamentals/101-sql-basics.md
  81. 2
      src/data/roadmaps/aspnet-core/content/107-databases/101-cloud/101-cosmosdb.md
  82. 1
      src/data/roadmaps/aspnet-core/content/107-databases/103-nosql/105-couchdb.md
  83. 1
      src/data/roadmaps/aspnet-core/content/107-databases/index.md
  84. 1
      src/data/roadmaps/aspnet-core/content/115-ci-cd/105-team-city.md
  85. 1
      src/data/roadmaps/aspnet-core/content/116-client-side-libraries/100-blazor.md
  86. 115
      src/data/roadmaps/backend/backend.md
  87. 1
      src/data/roadmaps/backend/content/100-internet/101-what-is-http.md
  88. 1
      src/data/roadmaps/backend/content/101-basic-frontend/101-css.md
  89. 2
      src/data/roadmaps/backend/content/102-os-general-knowledge/108-posix-basics.md
  90. 1
      src/data/roadmaps/backend/content/103-learn-a-language/103-csharp.md
  91. 1
      src/data/roadmaps/backend/content/104-version-control-systems/index.md
  92. 20
      src/data/roadmaps/backend/content/108-more-about-databases/105-failure-modes.md
  93. 10
      src/data/roadmaps/backend/content/108-more-about-databases/106-profiling-performance.md
  94. 1
      src/data/roadmaps/backend/content/109-apis/106-authentication/100-cookie-based.md
  95. 1
      src/data/roadmaps/backend/content/109-apis/106-authentication/103-token-authentication.md
  96. 2
      src/data/roadmaps/backend/content/109-scaling-databases/102-sharding-strategies.md
  97. 1
      src/data/roadmaps/backend/content/110-caching/100-cdn.md
  98. 1
      src/data/roadmaps/backend/content/110-caching/101-server-side/index.md
  99. 1
      src/data/roadmaps/backend/content/111-web-security-knowledge/101-sha-family.md
  100. 14
      src/data/roadmaps/backend/content/111-web-security-knowledge/106-server-security.md
  101. Some files were not shown because too many files have changed in this diff Show More

@ -0,0 +1,7 @@
app-dist
dist
.idea
.github
public
node_modules
pnpm-lock.yaml

@ -26,7 +26,7 @@ export default defineConfig({
'https://github.com/kamranahmedse', 'https://github.com/kamranahmedse',
'https://thenewstack.io', 'https://thenewstack.io',
'https://cs.fyi', 'https://cs.fyi',
'https://roadmap.sh' 'https://roadmap.sh',
]; ];
if (whiteListedStarts.some((start) => href.startsWith(start))) { if (whiteListedStarts.some((start) => href.startsWith(start))) {

@ -3,7 +3,10 @@ const path = require('path');
const CONTENT_DIR = path.join(__dirname, '../content'); const CONTENT_DIR = path.join(__dirname, '../content');
// Directory containing the best-practices // Directory containing the best-practices
const BEST_PRACTICE_CONTENT_DIR = path.join(__dirname, '../src/data/best-practices'); const BEST_PRACTICE_CONTENT_DIR = path.join(
__dirname,
'../src/data/best-practices'
);
const bestPracticeId = process.argv[2]; const bestPracticeId = process.argv[2];
const allowedBestPracticeId = fs.readdirSync(BEST_PRACTICE_CONTENT_DIR); const allowedBestPracticeId = fs.readdirSync(BEST_PRACTICE_CONTENT_DIR);
@ -28,7 +31,10 @@ if (!bestPracticeDirName) {
process.exit(1); process.exit(1);
} }
const bestPracticeDirPath = path.join(BEST_PRACTICE_CONTENT_DIR, bestPracticeDirName); const bestPracticeDirPath = path.join(
BEST_PRACTICE_CONTENT_DIR,
bestPracticeDirName
);
const bestPracticeContentDirPath = path.join( const bestPracticeContentDirPath = path.join(
BEST_PRACTICE_CONTENT_DIR, BEST_PRACTICE_CONTENT_DIR,
bestPracticeDirName, bestPracticeDirName,
@ -37,7 +43,9 @@ const bestPracticeContentDirPath = path.join(
// If best practice content already exists do not proceed as it would override the files // If best practice content already exists do not proceed as it would override the files
if (fs.existsSync(bestPracticeContentDirPath)) { if (fs.existsSync(bestPracticeContentDirPath)) {
console.error(`Best Practice content already exists @ ${bestPracticeContentDirPath}`); console.error(
`Best Practice content already exists @ ${bestPracticeContentDirPath}`
);
process.exit(1); process.exit(1);
} }
@ -51,7 +59,11 @@ function prepareDirTree(control, dirTree) {
const controlName = control?.properties?.controlName || ''; const controlName = control?.properties?.controlName || '';
// No directory for a group without control name // No directory for a group without control name
if (!controlName || controlName.startsWith('check:') || controlName.startsWith('ext_link:')) { if (
!controlName ||
controlName.startsWith('check:') ||
controlName.startsWith('ext_link:')
) {
return; return;
} }
@ -76,7 +88,10 @@ function prepareDirTree(control, dirTree) {
return { dirTree }; return { dirTree };
} }
const bestPractice = require(path.join(__dirname, `../public/jsons/best-practices/${bestPracticeId}`)); const bestPractice = require(path.join(
__dirname,
`../public/jsons/best-practices/${bestPracticeId}`
));
const controls = bestPractice.mockup.controls.control; const controls = bestPractice.mockup.controls.control;
// Prepare the dir tree that we will be creating // Prepare the dir tree that we will be creating
@ -129,11 +144,7 @@ function createDirTree(parentDir, dirTree, filePaths = {}) {
// For each of the directory names, create a // For each of the directory names, create a
// directory inside the given directory // directory inside the given directory
childrenDirNames.forEach((dirName) => { childrenDirNames.forEach((dirName) => {
createDirTree( createDirTree(path.join(parentDir, dirName), dirTree[dirName], filePaths);
path.join(parentDir, dirName),
dirTree[dirName],
filePaths
);
}); });
return filePaths; return filePaths;

@ -1,4 +1,5 @@
## CLI Tools ## CLI Tools
> A bunch of CLI scripts to make the development easier > A bunch of CLI scripts to make the development easier
## `roadmap-links.cjs` ## `roadmap-links.cjs`
@ -34,5 +35,3 @@ For the content skeleton to be generated, we should have proper grouping, and th
- Assign the name to the groups. - Assign the name to the groups.
- Group names have the format of `[sort]-[slug]` e.g. `100-internet`. Each group name should start with a number starting from 100 which helps with sorting of the directories and the files. Groups at the same level have the sequential sorting information. - Group names have the format of `[sort]-[slug]` e.g. `100-internet`. Each group name should start with a number starting from 100 which helps with sorting of the directories and the files. Groups at the same level have the sequential sorting information.
- Each groups children have a separate group and have the name similar to `[sort]-[parent-slug]:[child-slug]` where sort refers to the sorting of the `child-slug` and not the parent. Also parent-slug does not need to have the sorting information as a part of slug e.g. if parent was `100-internet` the children would be `100-internet:how-does-the-internet-work`, `101-internet:what-is-http`, `102-internet:browsers`. - Each groups children have a separate group and have the name similar to `[sort]-[parent-slug]:[child-slug]` where sort refers to the sorting of the `child-slug` and not the parent. Also parent-slug does not need to have the sorting information as a part of slug e.g. if parent was `100-internet` the children would be `100-internet:how-does-the-internet-work`, `101-internet:what-is-http`, `102-internet:browsers`.

@ -95,7 +95,9 @@ async function run() {
const roadmapJson = require(path.join(ROADMAP_JSON_DIR, `${roadmapId}.json`)); const roadmapJson = require(path.join(ROADMAP_JSON_DIR, `${roadmapId}.json`));
const groups = roadmapJson?.mockup?.controls?.control?.filter( const groups = roadmapJson?.mockup?.controls?.control?.filter(
(control) => control.typeID === '__group__' && !control.properties?.controlName?.startsWith('ext_link') (control) =>
control.typeID === '__group__' &&
!control.properties?.controlName?.startsWith('ext_link')
); );
if (!OPEN_AI_API_KEY) { if (!OPEN_AI_API_KEY) {
@ -106,8 +108,9 @@ async function run() {
for (let group of groups) { for (let group of groups) {
const topicId = group?.properties?.controlName; const topicId = group?.properties?.controlName;
const topicTitle = group?.children?.controls?.control?.find((control) => control?.typeID === 'Label')?.properties const topicTitle = group?.children?.controls?.control?.find(
?.text; (control) => control?.typeID === 'Label'
)?.properties?.text;
const currTopicUrl = topicId.replace(/^\d+-/g, '/').replace(/:/g, '/'); const currTopicUrl = topicId.replace(/^\d+-/g, '/').replace(/:/g, '/');
const contentFilePath = topicUrlToPathMapping[currTopicUrl]; const contentFilePath = topicUrlToPathMapping[currTopicUrl];

@ -82,7 +82,10 @@ function prepareDirTree(control, dirTree, dirSortOrders) {
return { dirTree, dirSortOrders }; return { dirTree, dirSortOrders };
} }
const roadmap = require(path.join(__dirname, `../public/jsons/roadmaps/${roadmapId}`)); const roadmap = require(path.join(
__dirname,
`../public/jsons/roadmaps/${roadmapId}`
));
const controls = roadmap.mockup.controls.control; const controls = roadmap.mockup.controls.control;
// Prepare the dir tree that we will be creating and also calculate the sort orders // Prepare the dir tree that we will be creating and also calculate the sort orders

@ -27,15 +27,24 @@ function populatePageAds({
const isConfiguredActive = isActive.toLowerCase() === 'yes'; const isConfiguredActive = isActive.toLowerCase() === 'yes';
const currentDate = new Date(); const currentDate = new Date();
const isDateInRange = currentDate >= new Date(startDate) && currentDate <= new Date(endDate); const isDateInRange =
currentDate >= new Date(startDate) && currentDate <= new Date(endDate);
const shouldShowAd = isConfiguredActive && isDateInRange; const shouldShowAd = isConfiguredActive && isDateInRange;
const urlPart = pageUrl.replace('https://roadmap.sh/', '').replace(/\?.+?$/, ''); const urlPart = pageUrl
.replace('https://roadmap.sh/', '')
.replace(/\?.+?$/, '');
const parentDir = urlPart.startsWith('best-practices/') ? 'best-practices' : 'roadmaps'; const parentDir = urlPart.startsWith('best-practices/')
? 'best-practices'
: 'roadmaps';
const pageId = urlPart.replace(`${parentDir}/`, ''); const pageId = urlPart.replace(`${parentDir}/`, '');
const pageFilePath = path.join(__dirname, `../src/data/${parentDir}`, `${pageId}/${pageId}.md`); const pageFilePath = path.join(
__dirname,
`../src/data/${parentDir}`,
`${pageId}/${pageId}.md`
);
if (!fs.existsSync(pageFilePath)) { if (!fs.existsSync(pageFilePath)) {
console.error(`Page file not found: ${pageFilePath}`); console.error(`Page file not found: ${pageFilePath}`);
@ -48,7 +57,9 @@ function populatePageAds({
const frontMatterRegex = /---\n([\s\S]*?)\n---/; const frontMatterRegex = /---\n([\s\S]*?)\n---/;
const existingFrontmatter = pageFileContent.match(frontMatterRegex)[1]; const existingFrontmatter = pageFileContent.match(frontMatterRegex)[1];
const contentWithoutFrontmatter = pageFileContent.replace(frontMatterRegex, ``).trim(); const contentWithoutFrontmatter = pageFileContent
.replace(frontMatterRegex, ``)
.trim();
let frontmatterObj = yaml.load(existingFrontmatter); let frontmatterObj = yaml.load(existingFrontmatter);
delete frontmatterObj.sponsor; delete frontmatterObj.sponsor;
@ -77,7 +88,11 @@ function populatePageAds({
frontmatterObj = Object.fromEntries(frontmatterValues); frontmatterObj = Object.fromEntries(frontmatterValues);
} }
const newFrontmatter = yaml.dump(frontmatterObj, { lineWidth: 10000, forceQuotes: true, quotingType: '"' }); const newFrontmatter = yaml.dump(frontmatterObj, {
lineWidth: 10000,
forceQuotes: true,
quotingType: '"',
});
const newContent = `---\n${newFrontmatter}---\n\n${contentWithoutFrontmatter}`; const newContent = `---\n${newFrontmatter}---\n\n${contentWithoutFrontmatter}`;
fs.writeFileSync(pageFilePath, newContent, 'utf8'); fs.writeFileSync(pageFilePath, newContent, 'utf8');

@ -14,21 +14,21 @@ appearance, race, religion, or sexual identity and orientation.
Examples of behavior that contributes to creating a positive environment Examples of behavior that contributes to creating a positive environment
include: include:
* Using welcoming and inclusive language - Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences - Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism - Gracefully accepting constructive criticism
* Focusing on what is best for the community - Focusing on what is best for the community
* Showing empathy towards other community members - Showing empathy towards other community members
Examples of unacceptable behavior by participants include: Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or - The use of sexualized language or imagery and unwelcome sexual attention or
advances advances
* Trolling, insulting/derogatory comments, and personal or political attacks - Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment - Public or private harassment
* Publishing others' private information, such as a physical or electronic - Publishing others' private information, such as a physical or electronic
address, without explicit permission address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a - Other conduct which could reasonably be considered inappropriate in a
professional setting professional setting
## Our Responsibilities ## Our Responsibilities

@ -8,6 +8,7 @@
"start": "astro dev", "start": "astro dev",
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"format": "prettier --write .",
"astro": "astro", "astro": "astro",
"deploy": "NODE_DEBUG=gh-pages gh-pages -d dist -t", "deploy": "NODE_DEBUG=gh-pages gh-pages -d dist -t",
"compress:jsons": "node bin/compress-jsons.cjs", "compress:jsons": "node bin/compress-jsons.cjs",

@ -100,7 +100,7 @@ const config: PlaywrightTestConfig = {
/* Run your local dev server before starting the tests */ /* Run your local dev server before starting the tests */
webServer: { webServer: {
command: 'npm run dev', command: 'npm run dev',
url: "http://localhost:3000", url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI, reuseExistingServer: !process.env.CI,
}, },
}; };

File diff suppressed because it is too large Load Diff

@ -27,8 +27,13 @@ export async function serializeSitemap(item) {
'https://roadmap.sh/best-practices', 'https://roadmap.sh/best-practices',
'https://roadmap.sh/guides', 'https://roadmap.sh/guides',
'https://roadmap.sh/videos', 'https://roadmap.sh/videos',
...(await getRoadmapIds()).flatMap((id) => [`https://roadmap.sh/${id}`, `https://roadmap.sh/${id}/topics`]), ...(await getRoadmapIds()).flatMap((id) => [
...(await getBestPracticesIds()).map((id) => `https://roadmap.sh/best-practices/${id}`), `https://roadmap.sh/${id}`,
`https://roadmap.sh/${id}/topics`,
]),
...(await getBestPracticesIds()).map(
(id) => `https://roadmap.sh/best-practices/${id}`
),
]; ];
// Roadmaps and other high priority pages // Roadmaps and other high priority pages
@ -44,7 +49,10 @@ export async function serializeSitemap(item) {
} }
// Guide and video pages // Guide and video pages
if (item.url.startsWith('https://roadmap.sh/guides') || item.url.startsWith('https://roadmap.sh/videos')) { if (
item.url.startsWith('https://roadmap.sh/guides') ||
item.url.startsWith('https://roadmap.sh/videos')
) {
return { return {
...item, ...item,
// @ts-ignore // @ts-ignore

@ -15,9 +15,12 @@ export class Topic {
this.activeTopicId = null; this.activeTopicId = null;
this.handleRoadmapTopicClick = this.handleRoadmapTopicClick.bind(this); this.handleRoadmapTopicClick = this.handleRoadmapTopicClick.bind(this);
this.handleBestPracticeTopicClick = this.handleBestPracticeTopicClick.bind(this); this.handleBestPracticeTopicClick =
this.handleBestPracticeTopicToggle = this.handleBestPracticeTopicToggle.bind(this); this.handleBestPracticeTopicClick.bind(this);
this.handleBestPracticeTopicPending = this.handleBestPracticeTopicPending.bind(this); this.handleBestPracticeTopicToggle =
this.handleBestPracticeTopicToggle.bind(this);
this.handleBestPracticeTopicPending =
this.handleBestPracticeTopicPending.bind(this);
this.close = this.close.bind(this); this.close = this.close.bind(this);
this.resetDOM = this.resetDOM.bind(this); this.resetDOM = this.resetDOM.bind(this);
@ -178,7 +181,10 @@ export class Topic {
this.resetDOM(); this.resetDOM();
const topicUrl = `/best-practices/${bestPracticeId}/${topicId.replaceAll(':', '/')}`; const topicUrl = `/best-practices/${bestPracticeId}/${topicId.replaceAll(
':',
'/'
)}`;
this.renderTopicFromUrl(topicUrl).then(() => null); this.renderTopicFromUrl(topicUrl).then(() => null);
} }
@ -210,7 +216,9 @@ export class Topic {
const matchingElements = []; const matchingElements = [];
// Elements having sort order in the beginning of the group id // Elements having sort order in the beginning of the group id
document.querySelectorAll(`[data-group-id$="-${topicId}"]`).forEach((element) => { document
.querySelectorAll(`[data-group-id$="-${topicId}"]`)
.forEach((element) => {
const foundGroupId = element?.dataset?.groupId || ''; const foundGroupId = element?.dataset?.groupId || '';
const validGroupRegex = new RegExp(`^\\d+-${topicId}$`); const validGroupRegex = new RegExp(`^\\d+-${topicId}$`);
@ -220,12 +228,16 @@ export class Topic {
}); });
// Elements with exact match of the topic id // Elements with exact match of the topic id
document.querySelectorAll(`[data-group-id="${topicId}"]`).forEach((element) => { document
.querySelectorAll(`[data-group-id="${topicId}"]`)
.forEach((element) => {
matchingElements.push(element); matchingElements.push(element);
}); });
// Matching "check:XXXX" box of the topic // Matching "check:XXXX" box of the topic
document.querySelectorAll(`[data-group-id="check:${topicId}"]`).forEach((element) => { document
.querySelectorAll(`[data-group-id="check:${topicId}"]`)
.forEach((element) => {
matchingElements.push(element); matchingElements.push(element);
}); });
@ -258,29 +270,44 @@ export class Topic {
return; return;
} }
const isClickedDone = e.target.id === this.markTopicDoneId || e.target.closest(`#${this.markTopicDoneId}`); const isClickedDone =
e.target.id === this.markTopicDoneId ||
e.target.closest(`#${this.markTopicDoneId}`);
if (isClickedDone) { if (isClickedDone) {
this.markAsDone(this.activeTopicId); this.markAsDone(this.activeTopicId);
this.close(); this.close();
} }
const isClickedPending = e.target.id === this.markTopicPendingId || e.target.closest(`#${this.markTopicPendingId}`); const isClickedPending =
e.target.id === this.markTopicPendingId ||
e.target.closest(`#${this.markTopicPendingId}`);
if (isClickedPending) { if (isClickedPending) {
this.markAsPending(this.activeTopicId); this.markAsPending(this.activeTopicId);
this.close(); this.close();
} }
const isClickedClose = e.target.id === this.closeTopicId || e.target.closest(`#${this.closeTopicId}`); const isClickedClose =
e.target.id === this.closeTopicId ||
e.target.closest(`#${this.closeTopicId}`);
if (isClickedClose) { if (isClickedClose) {
this.close(); this.close();
} }
} }
init() { init() {
window.addEventListener('best-practice.topic.click', this.handleBestPracticeTopicClick); window.addEventListener(
window.addEventListener('best-practice.topic.toggle', this.handleBestPracticeTopicToggle); 'best-practice.topic.click',
this.handleBestPracticeTopicClick
window.addEventListener('roadmap.topic.click', this.handleRoadmapTopicClick); );
window.addEventListener(
'best-practice.topic.toggle',
this.handleBestPracticeTopicToggle
);
window.addEventListener(
'roadmap.topic.click',
this.handleRoadmapTopicClick
);
window.addEventListener('click', this.handleOverlayClick); window.addEventListener('click', this.handleOverlayClick);
window.addEventListener('contextmenu', this.rightClickListener); window.addEventListener('contextmenu', this.rightClickListener);

@ -1,37 +1,36 @@
--- ---
jsonUrl: "/jsons/best-practices/api-security.json" jsonUrl: '/jsons/best-practices/api-security.json'
pdfUrl: "/pdfs/best-practices/api-security.pdf" pdfUrl: '/pdfs/best-practices/api-security.pdf'
order: 2 order: 2
briefTitle: "API Security" briefTitle: 'API Security'
briefDescription: "API Security Best Practices" briefDescription: 'API Security Best Practices'
isNew: true isNew: true
isUpcoming: false isUpcoming: false
title: "API Security Best Practices" title: 'API Security Best Practices'
description: "Detailed list of best practices to make your APIs secure" description: 'Detailed list of best practices to make your APIs secure'
dimensions: dimensions:
width: 968 width: 968
height: 1543.39 height: 1543.39
sponsor: sponsor:
url: "https://www.getambassador.io/products/edge-stack-api-gateway?utm_source=roadmap-sh&utm_medium=edge-stack-page&utm_campaign=new-account" url: 'https://www.getambassador.io/products/edge-stack-api-gateway?utm_source=roadmap-sh&utm_medium=edge-stack-page&utm_campaign=new-account'
title: "Featured Product" title: 'Featured Product'
imageUrl: "https://i.imgur.com/e5fdI0q.png" imageUrl: 'https://i.imgur.com/e5fdI0q.png'
description: "Get your Kubernetes API Gateway up and running in 5 minutes with Ambassador Edge Stack!" description: 'Get your Kubernetes API Gateway up and running in 5 minutes with Ambassador Edge Stack!'
event: event:
category: "SponsorClick" category: 'SponsorClick'
action: "Ambassador Redirect" action: 'Ambassador Redirect'
label: "API Security / Ambassador Link" label: 'API Security / Ambassador Link'
schema: schema:
headline: "API Security Best Practices" headline: 'API Security Best Practices'
description: "Detailed list of best practices to make your APIs secure. Each best practice carries further details and how to implement that best practice." description: 'Detailed list of best practices to make your APIs secure. Each best practice carries further details and how to implement that best practice.'
imageUrl: "https://roadmap.sh/best-practices/api-security.png" imageUrl: 'https://roadmap.sh/best-practices/api-security.png'
datePublished: "2023-02-21" datePublished: '2023-02-21'
dateModified: "2023-02-21" dateModified: '2023-02-21'
seo: seo:
title: "API Security Best Practices" title: 'API Security Best Practices'
description: "Detailed list of best practices to make your APIs secure. Each best practice carries further details and how to implement that best practice." description: 'Detailed list of best practices to make your APIs secure. Each best practice carries further details and how to implement that best practice.'
keywords: keywords:
- "API Security" - 'API Security'
- "API Security Best Practices" - 'API Security Best Practices'
- "API Security Checklist" - 'API Security Checklist'
--- ---

@ -1,6 +1,6 @@
# Endpoint Authentication # Endpoint Authentication
> Check if all the protected endpoints are behind authentication > Check if all the protected endpoints are behind authentication
to avoid broken authentication process > to avoid broken authentication process
By identifying and fixing broken authentication workflows, the API can prevent attacks such as brute force attacks, credential stuffing, session hijacking, and other authentication-related attacks. This can help ensure that the system is secure and that sensitive data is protected. By identifying and fixing broken authentication workflows, the API can prevent attacks such as brute force attacks, credential stuffing, session hijacking, and other authentication-related attacks. This can help ensure that the system is secure and that sensitive data is protected.

@ -1,5 +1,3 @@
# Proper HTTP Methods # Proper HTTP Methods
Use the proper HTTP method according to the operation: `GET (read)`, `POST (create)`, `PUT/PATCH (replace/update)`, and `DELETE (to delete a record)`, and respond with `405 Method Not Allowed` if the requested method isn't appropriate for the requested resource. Use the proper HTTP method according to the operation: `GET (read)`, `POST (create)`, `PUT/PATCH (replace/update)`, and `DELETE (to delete a record)`, and respond with `405 Method Not Allowed` if the requested method isn't appropriate for the requested resource.

@ -1,6 +1,7 @@
# Proper Response Code # Proper Response Code
> Return the proper status code according to the operation completed. e.g. > Return the proper status code according to the operation completed. e.g.
>
> - `200 OK` > - `200 OK`
> - `400 Bad Request` > - `400 Bad Request`
> - `401 Unauthorized` > - `401 Unauthorized`

@ -3,4 +3,3 @@
> Private APIs should only be accessible from safe listed IPs > Private APIs should only be accessible from safe listed IPs
Private APIs should only be accessible from safe-listed IPs to ensure that only authorized users or systems can access the API. By restricting access to specific IP addresses, you can prevent unauthorized access from external networks or malicious actors. This can help to protect sensitive data and prevent attacks such as DDoS or brute-force attacks. Additionally, restricting access to safe-listed IPs can help to ensure the reliability and performance of the API by preventing excessive traffic from unauthorized sources. Private APIs should only be accessible from safe-listed IPs to ensure that only authorized users or systems can access the API. By restricting access to specific IP addresses, you can prevent unauthorized access from external networks or malicious actors. This can help to protect sensitive data and prevent attacks such as DDoS or brute-force attacks. Additionally, restricting access to safe-listed IPs can help to ensure the reliability and performance of the API by preventing excessive traffic from unauthorized sources.

@ -5,4 +5,3 @@
Ensure that your API server uses HTTPS instead of HTTP. HTTPS is a secure protocol that encrypts data in transit, making it difficult for attackers to intercept and read sensitive information. To implement HTTPS, you need to obtain an SSL/TLS certificate and configure your server to use HTTPS. Ensure that your API server uses HTTPS instead of HTTP. HTTPS is a secure protocol that encrypts data in transit, making it difficult for attackers to intercept and read sensitive information. To implement HTTPS, you need to obtain an SSL/TLS certificate and configure your server to use HTTPS.
HTTPS uses ciphers to encrypt data in transit. It is important to choose secure ciphers that are resistant to attacks and offer strong encryption. Some common secure ciphers include AES, ChaCha20, and ECDHE for key exchange. Make sure to disable weak and outdated ciphers, such as RC4 and TLS 1.0/1.1, which are vulnerable to attacks. HTTPS uses ciphers to encrypt data in transit. It is important to choose secure ciphers that are resistant to attacks and offer strong encryption. Some common secure ciphers include AES, ChaCha20, and ECDHE for key exchange. Make sure to disable weak and outdated ciphers, such as RC4 and TLS 1.0/1.1, which are vulnerable to attacks.

@ -3,4 +3,3 @@
> Validate `content-type` on request headers to prevent XSS attacks > Validate `content-type` on request headers to prevent XSS attacks
Validating the `Content-Type` header on the request can help to make APIs more secure by ensuring that the request data is in the expected format and reducing the risk of attacks such as injection attacks or cross-site scripting (XSS). Validating the `Content-Type` header on the request can help to make APIs more secure by ensuring that the request data is in the expected format and reducing the risk of attacks such as injection attacks or cross-site scripting (XSS).

@ -2,5 +2,4 @@
> Pre-warm your ELBs if you're expecting heavy traffic. > Pre-warm your ELBs if you're expecting heavy traffic.
It takes time for your ELB to scale up capacity. If you know you're going to have a large traffic spike (selling tickets, big event, etc), you need to "warm up" your ELB in advance. You can inject a load of traffic, and it will cause ELB to scale up and not choke when you actually get the traffic, however AWS suggest you contact them instead to prewarm your load balancer. (Source: [Best Practices in Evaluating Elastic Load Balancing](https://aws.amazon.com/articles/best-practices-in-evaluating-elastic-load-balancing/#pre-warming)). Alternatively you can install your own load balancer software on an EC2 instance and use that instead (HAProxy, etc). It takes time for your ELB to scale up capacity. If you know you're going to have a large traffic spike (selling tickets, big event, etc), you need to "warm up" your ELB in advance. You can inject a load of traffic, and it will cause ELB to scale up and not choke when you actually get the traffic, however AWS suggest you contact them instead to prewarm your load balancer. (Source: [Best Practices in Evaluating Elastic Load Balancing](https://aws.amazon.com/articles/best-practices-in-evaluating-elastic-load-balancing/#pre-warming)). Alternatively you can install your own load balancer software on an EC2 instance and use that instead (HAProxy, etc).

@ -3,5 +3,3 @@
> Set up automated security auditing. > Set up automated security auditing.
It's important to keep track of changes in your infrastructure's security settings. One way to do this is to first set up a security auditer role ([JSON template](https://gist.github.com/bigsnarfdude/d0758b4fd335085623be)), which will give anyone assigned that role read-only access to any security related settings on your account. You can then use this rather [fantastic Python script](https://gist.github.com/jlevy/cce1b44fc24f94599d0a4b3e613cc15d), which will go over all the items in your account and produce a canonical output showing your configuration. You set up a cronjob somewhere to run this script, and compare its output to the output from the previous run. Any differences will show you exactly what has been changed in your security configuration. It's useful to set this up and just have it email you the diff of any changes. (Source: Intrusion Detection in the Cloud - [Presentation](http://awsmedia.s3.amazonaws.com/SEC402.pdf)) It's important to keep track of changes in your infrastructure's security settings. One way to do this is to first set up a security auditer role ([JSON template](https://gist.github.com/bigsnarfdude/d0758b4fd335085623be)), which will give anyone assigned that role read-only access to any security related settings on your account. You can then use this rather [fantastic Python script](https://gist.github.com/jlevy/cce1b44fc24f94599d0a4b3e613cc15d), which will go over all the items in your account and produce a canonical output showing your configuration. You set up a cronjob somewhere to run this script, and compare its output to the output from the previous run. Any differences will show you exactly what has been changed in your security configuration. It's useful to set this up and just have it email you the diff of any changes. (Source: Intrusion Detection in the Cloud - [Presentation](http://awsmedia.s3.amazonaws.com/SEC402.pdf))

@ -5,4 +5,3 @@
Usually you'll have an "operations account" for a service, and your entire ops team will have the password. With AWS, you definitely don't want to do that. Everyone gets an IAM user with just the permissions they need (least privilege). An IAM user can control everything in the infrastructure. At the time of writing, the only thing an IAM user can't access are some parts of the billing pages. Usually you'll have an "operations account" for a service, and your entire ops team will have the password. With AWS, you definitely don't want to do that. Everyone gets an IAM user with just the permissions they need (least privilege). An IAM user can control everything in the infrastructure. At the time of writing, the only thing an IAM user can't access are some parts of the billing pages.
If you want to protect your account even more, make sure to [enable multi-factor authentication](http://aws.amazon.com/iam/details/mfa/) for everyone (you can use Google Authenticator). I've heard of some users who give the MFA token to two people, and the password to two others, so to perform any action on the master account, two of the users need to agree. This is overkill for my case, but worth mentioning in case someone else wants to do it. If you want to protect your account even more, make sure to [enable multi-factor authentication](http://aws.amazon.com/iam/details/mfa/) for everyone (you can use Google Authenticator). I've heard of some users who give the MFA token to two people, and the password to two others, so to perform any action on the master account, two of the users need to agree. This is overkill for my case, but worth mentioning in case someone else wants to do it.

@ -6,5 +6,4 @@ Most of the time, new versions come with optimization and security fix. You shou
If your project use NPM packages, [npm-check](https://www.npmjs.com/package/npm-check) is a pretty interesting library to upgrade / update your libraries. [Greenkeeper](https://greenkeeper.io/) can automatically look for your dependencies and suggest an update every time a new version is out. If your project use NPM packages, [npm-check](https://www.npmjs.com/package/npm-check) is a pretty interesting library to upgrade / update your libraries. [Greenkeeper](https://greenkeeper.io/) can automatically look for your dependencies and suggest an update every time a new version is out.
- [Vanilla JavaScript for building powerful web applications](https://plainjs.com/) - [Vanilla JavaScript for building powerful web applications](https://plainjs.com/)

@ -1,4 +1,5 @@
# Minify HTML # Minify HTML
> The HTML code is minified, comments, white spaces and new lines are removed from production files. > The HTML code is minified, comments, white spaces and new lines are removed from production files.
Removing all unnecessary spaces, comments and attributes will reduce the size of your HTML and speed up your site's page load times and obviously lighten the download for your user. Removing all unnecessary spaces, comments and attributes will reduce the size of your HTML and speed up your site's page load times and obviously lighten the download for your user.

@ -1,4 +1,5 @@
# Page Load Time # Page Load Time
> Reduce as much as possible your page load times to quickly deliver your content to your users. > Reduce as much as possible your page load times to quickly deliver your content to your users.
Faster your website or app is, less you have probability of bounce increases, in other terms you have less chances to lose your user or future client. Enough researches on the subject prove that point. Faster your website or app is, less you have probability of bounce increases, in other terms you have less chances to lose your user or future client. Enough researches on the subject prove that point.

@ -2,89 +2,89 @@
> Optimize the critical rendering path: > Optimize the critical rendering path:
* [Critical CSS? Not So Fast!](https://csswizardry.com/2022/09/critical-css-not-so-fast/) - [Critical CSS? Not So Fast!](https://csswizardry.com/2022/09/critical-css-not-so-fast/)
* [Priority Hints - What Your Browser Doesn’t Know (Yet)](https://www.etsy.com/codeascraft/priority-hints-what-your-browser-doesnt-know-yet) - [Priority Hints - What Your Browser Doesn’t Know (Yet)](https://www.etsy.com/codeascraft/priority-hints-what-your-browser-doesnt-know-yet)
* [Optimizing resource loading with Priority Hints](https://web.dev/priority-hints/) - [Optimizing resource loading with Priority Hints](https://web.dev/priority-hints/)
* [Chrome Resource Priorities and Scheduling](https://docs.google.com/document/d/1bCDuq9H1ih9iNjgzyAL0gpwNFiEP4TZS-YLRp_RuMlc/edit?usp=sharing) - [Chrome Resource Priorities and Scheduling](https://docs.google.com/document/d/1bCDuq9H1ih9iNjgzyAL0gpwNFiEP4TZS-YLRp_RuMlc/edit?usp=sharing)
* [How To Optimize CSS for Peak Site Performance](https://kinsta.com/blog/optimize-css/) - [How To Optimize CSS for Peak Site Performance](https://kinsta.com/blog/optimize-css/)
* [Eliminate render blocking CSS to improve start render time](https://www.jeffreyknox.dev/blog/eliminate-render-blocking-css-to-improve-start-render-time/) - [Eliminate render blocking CSS to improve start render time](https://www.jeffreyknox.dev/blog/eliminate-render-blocking-css-to-improve-start-render-time/)
* [Small Bundles, Fast Pages: What To Do With Too Much JavaScript](https://calibreapp.com/blog/bundle-size-optimization) - [Small Bundles, Fast Pages: What To Do With Too Much JavaScript](https://calibreapp.com/blog/bundle-size-optimization)
* [How to Eliminate Render-Blocking Resources: a Deep Dive](https://sia.codes/posts/render-blocking-resources/) - [How to Eliminate Render-Blocking Resources: a Deep Dive](https://sia.codes/posts/render-blocking-resources/)
* [The Critical Request: How to Prioritise Requests to Improve Speed](https://calibreapp.com/blog/critical-request) - [The Critical Request: How to Prioritise Requests to Improve Speed](https://calibreapp.com/blog/critical-request)
* [How to Improve CSS Performance](https://calibreapp.com/blog/css-performance) - [How to Improve CSS Performance](https://calibreapp.com/blog/css-performance)
* [The Simplest Way to Load CSS Asynchronously](https://www.filamentgroup.com/lab/load-css-simpler/) - [The Simplest Way to Load CSS Asynchronously](https://www.filamentgroup.com/lab/load-css-simpler/)
* [CSS audit](https://css-tricks.com/a-quick-css-audit-and-general-notes-about-design-systems/) - [CSS audit](https://css-tricks.com/a-quick-css-audit-and-general-notes-about-design-systems/)
* [Measuring the Critical Rendering Path](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/measure-crp) - [Measuring the Critical Rendering Path](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/measure-crp)
* [Inlining or Caching? Both Please!](https://www.filamentgroup.com/lab/inlining-cache.html) - [Inlining or Caching? Both Please!](https://www.filamentgroup.com/lab/inlining-cache.html)
* [CSS and Network Performance](https://csswizardry.com/2018/11/css-and-network-performance/) - [CSS and Network Performance](https://csswizardry.com/2018/11/css-and-network-performance/)
* [Analyzing Critical Rendering Path Performance](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/analyzing-crp) - [Analyzing Critical Rendering Path Performance](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/analyzing-crp)
* [Front-End Performance Checklist](https://github.com/thedaviddias/Front-End-Performance-Checklist) - [Front-End Performance Checklist](https://github.com/thedaviddias/Front-End-Performance-Checklist)
* [The PRPL Pattern](https://developers.google.com/web/fundamentals/performance/prpl-pattern/) - [The PRPL Pattern](https://developers.google.com/web/fundamentals/performance/prpl-pattern/)
* [Now You See Me: How To Defer, Lazy-Load And Act With IntersectionObserver](https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/) - [Now You See Me: How To Defer, Lazy-Load And Act With IntersectionObserver](https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/)
* [Optimising the front end for the browser](https://hackernoon.com/optimising-the-front-end-for-the-browser-f2f51a29c572) - [Optimising the front end for the browser](https://hackernoon.com/optimising-the-front-end-for-the-browser-f2f51a29c572)
* [Prefer DEFER Over ASYNC](https://calendar.perfplanet.com/2016/prefer-defer-over-async/) - [Prefer DEFER Over ASYNC](https://calendar.perfplanet.com/2016/prefer-defer-over-async/)
* [A comprehensive guide to font loading strategies](https://www.zachleat.com/web/comprehensive-webfonts/) - [A comprehensive guide to font loading strategies](https://www.zachleat.com/web/comprehensive-webfonts/)
* [Understanding the critical rendering path, rendering pages in 1 second](https://medium.com/@luisvieira_gmr/understanding-the-critical-rendering-path-rendering-pages-in-1-second-735c6e45b47a) - [Understanding the critical rendering path, rendering pages in 1 second](https://medium.com/@luisvieira_gmr/understanding-the-critical-rendering-path-rendering-pages-in-1-second-735c6e45b47a)
* [More Weight Doesn’t Mean More Wait](https://www.filamentgroup.com/lab/weight-wait.html) - [More Weight Doesn’t Mean More Wait](https://www.filamentgroup.com/lab/weight-wait.html)
> JavaScript Rendering Performance > JavaScript Rendering Performance
* [Five Data-Loading Patterns To Boost Web Performance](https://www.smashingmagazine.com/2022/09/data-loading-patterns-improve-frontend-performance/) - [Five Data-Loading Patterns To Boost Web Performance](https://www.smashingmagazine.com/2022/09/data-loading-patterns-improve-frontend-performance/)
* [Optimize long tasks](https://web.dev/optimize-long-tasks/) - [Optimize long tasks](https://web.dev/optimize-long-tasks/)
* [The impact of removing jQuery on our web performance](https://insidegovuk.blog.gov.uk/2022/08/15/the-impact-of-removing-jquery-on-our-web-performance/) - [The impact of removing jQuery on our web performance](https://insidegovuk.blog.gov.uk/2022/08/15/the-impact-of-removing-jquery-on-our-web-performance/)
* [Profiling & Optimizing the runtime performance with the DevTools Performance tab](iamtk.co/profiling-and-optimizing-the-runtime-performance-with-the-devtools-performance-tab) - [Profiling & Optimizing the runtime performance with the DevTools Performance tab](iamtk.co/profiling-and-optimizing-the-runtime-performance-with-the-devtools-performance-tab)
* [Don't fight the browser preload scanner](https://web.dev/preload-scanner/) - [Don't fight the browser preload scanner](https://web.dev/preload-scanner/)
* [The Web Performance impact of jQuery](https://twitter.com/TheRealNooshu/status/1509487050122276864) - [The Web Performance impact of jQuery](https://twitter.com/TheRealNooshu/status/1509487050122276864)
* [Have Single-Page Apps Ruined the Web? | Transitional Apps](https://www.youtube.com/watch?v=860d8usGC0o) - [Have Single-Page Apps Ruined the Web? | Transitional Apps](https://www.youtube.com/watch?v=860d8usGC0o)
* [Improve how you architect webapps](https://www.patterns.dev/) - [Improve how you architect webapps](https://www.patterns.dev/)
* [Nuxt SSR Optimizing Tips](https://vueschool.io/articles/vuejs-tutorials/nuxt-ssr-optimizing-tips/, Filip Rakowski - [Nuxt SSR Optimizing Tips](https://vueschool.io/articles/vuejs-tutorials/nuxt-ssr-optimizing-tips/, Filip Rakowski
* [GPU accelerated JavaScript](https://gpu.rocks/#/) - [GPU accelerated JavaScript](https://gpu.rocks/#/)
* [Introducing Partytown 🎉: Run Third-Party Scripts From a Web Worker](https://dev.to/adamdbradley/introducing-partytown-run-third-party-scripts-from-a-web-worker-2cnp) - [Introducing Partytown 🎉: Run Third-Party Scripts From a Web Worker](https://dev.to/adamdbradley/introducing-partytown-run-third-party-scripts-from-a-web-worker-2cnp)
* [Astro: Astro is a fresh but familiar approach to building websites. Astro combines decades of proven performance best practices with the DX improvements of the component-oriented era. Use your favorite JavaScript framework and automatically ship the bare-minimum amount of JavaScript—by default.](https://docs.astro.build/getting-started/) - [Astro: Astro is a fresh but familiar approach to building websites. Astro combines decades of proven performance best practices with the DX improvements of the component-oriented era. Use your favorite JavaScript framework and automatically ship the bare-minimum amount of JavaScript—by default.](https://docs.astro.build/getting-started/)
* [Minimising Layout and Layout thrashing for 60 FPS](https://www.charistheo.io/blog/2021/09/dom-reflow-and-layout-thrashing/) - [Minimising Layout and Layout thrashing for 60 FPS](https://www.charistheo.io/blog/2021/09/dom-reflow-and-layout-thrashing/)
* [Does shadow DOM improve style performance?](https://nolanlawson.com/2021/08/15/does-shadow-dom-improve-style-performance/) - [Does shadow DOM improve style performance?](https://nolanlawson.com/2021/08/15/does-shadow-dom-improve-style-performance/)
* [Debugging memory leaks - HTTP 203](https://www.youtube.com/watch?v=YDU_3WdfkxA) - [Debugging memory leaks - HTTP 203](https://www.youtube.com/watch?v=YDU_3WdfkxA)
* [Explore JavaScript Dependencies With Lighthouse Treemap](https://sia.codes/posts/lighthouse-treemap/) - [Explore JavaScript Dependencies With Lighthouse Treemap](https://sia.codes/posts/lighthouse-treemap/)
* [The real cost of Javascript dependencies (and the state of JS package quality)](https://medium.com/voodoo-engineering/the-real-cost-of-javascript-dependencies-and-the-state-of-js-package-quality-a8dacd74c0ec) - [The real cost of Javascript dependencies (and the state of JS package quality)](https://medium.com/voodoo-engineering/the-real-cost-of-javascript-dependencies-and-the-state-of-js-package-quality-a8dacd74c0ec)
* [The State Of Web Workers In 2021](https://www.smashingmagazine.com/2021/06/web-workers-2021/) - [The State Of Web Workers In 2021](https://www.smashingmagazine.com/2021/06/web-workers-2021/)
* [Techniques for developing high-performance animations](https://web.dev/animations/) - [Techniques for developing high-performance animations](https://web.dev/animations/)
* [Building a Faster Web Experience with the postTask Scheduler](https://medium.com/airbnb-engineering/building-a-faster-web-experience-with-the-posttask-scheduler-276b83454e91), Callie (Airbnb Engineering & Data Science) - [Building a Faster Web Experience with the postTask Scheduler](https://medium.com/airbnb-engineering/building-a-faster-web-experience-with-the-posttask-scheduler-276b83454e91), Callie (Airbnb Engineering & Data Science)
* [Don’t attach tooltips to document.body – Learn how the browser works – Debug forced reflow](https://atfzl.com/don-t-attach-tooltips-to-document-body) - [Don’t attach tooltips to document.body – Learn how the browser works – Debug forced reflow](https://atfzl.com/don-t-attach-tooltips-to-document-body)
* [How to Create and Fix Memory Leaks With Chrome DevTools](https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658) - [How to Create and Fix Memory Leaks With Chrome DevTools](https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658)
* [JavaScript performance beyond bundle size](https://nolanlawson.com/2021/02/23/javascript-performance-beyond-bundle-size/) - [JavaScript performance beyond bundle size](https://nolanlawson.com/2021/02/23/javascript-performance-beyond-bundle-size/)
* [The Import On Interaction Pattern](https://addyosmani.com/blog/import-on-interaction/) - [The Import On Interaction Pattern](https://addyosmani.com/blog/import-on-interaction/)
* [The “Live DOM” Is Not “Slow”, “Bad”, Or “Wrong”. Web Developers Are.](https://levelup.gitconnected.com/the-live-dom-is-not-slow-bad-or-wrong-web-developers-are-2bf86c3b9e2e) - [The “Live DOM” Is Not “Slow”, “Bad”, Or “Wrong”. Web Developers Are.](https://levelup.gitconnected.com/the-live-dom-is-not-slow-bad-or-wrong-web-developers-are-2bf86c3b9e2e)
* [Prevent layout shifts with CSS grid stacks](https://www.hsablonniere.com/prevent-layout-shifts-with-css-grid-stacks--qcj5jo/) - [Prevent layout shifts with CSS grid stacks](https://www.hsablonniere.com/prevent-layout-shifts-with-css-grid-stacks--qcj5jo/)
* [content-visibility: the new CSS property that boosts your rendering performance](https://web.dev/content-visibility/) - [content-visibility: the new CSS property that boosts your rendering performance](https://web.dev/content-visibility/)
* [Preact vs React - Updating React at Etsy](https://github.com/mq2thez/blog/blob/main/upgrade-react-etsy/preact-vs-react.md) - [Preact vs React - Updating React at Etsy](https://github.com/mq2thez/blog/blob/main/upgrade-react-etsy/preact-vs-react.md)
* [The Cost of Javascript Frameworks](https://timkadlec.com/remembers/2020-04-21-the-cost-of-javascript-frameworks/) - [The Cost of Javascript Frameworks](https://timkadlec.com/remembers/2020-04-21-the-cost-of-javascript-frameworks/)
* [Fixing memory leaks in web applications](https://nolanlawson.com/2020/02/19/fixing-memory-leaks-in-web-applications/) - [Fixing memory leaks in web applications](https://nolanlawson.com/2020/02/19/fixing-memory-leaks-in-web-applications/)
* [How to load polyfills only when needed](https://3perf.com/blog/polyfills/) - [How to load polyfills only when needed](https://3perf.com/blog/polyfills/)
* [Responsible JavaScript: Part III - Third parties](https://alistapart.com/article/responsible-javascript-part-3/) - [Responsible JavaScript: Part III - Third parties](https://alistapart.com/article/responsible-javascript-part-3/)
* [The cost of JavaScript in 2019](https://v8.dev/blog/cost-of-javascript-2019) - [The cost of JavaScript in 2019](https://v8.dev/blog/cost-of-javascript-2019)
* [When should you be using Web Workers?](https://dassur.ma/things/when-workers/) - [When should you be using Web Workers?](https://dassur.ma/things/when-workers/)
* [Responsible Javascript: Part II - Code Bundle](https://alistapart.com/article/responsible-javascript-part-2/) - [Responsible Javascript: Part II - Code Bundle](https://alistapart.com/article/responsible-javascript-part-2/)
* [Faster script loading with BinaryAST?](https://blog.cloudflare.com/binary-ast/) - [Faster script loading with BinaryAST?](https://blog.cloudflare.com/binary-ast/)
* [Svelte 3: Rethinking reactivity](https://svelte.dev/blog/svelte-3-rethinking-reactivity) - [Svelte 3: Rethinking reactivity](https://svelte.dev/blog/svelte-3-rethinking-reactivity)
* [Responsible Javascript: Part I - Web platform over frameworks](https://alistapart.com/article/responsible-javascript-part-1/) - [Responsible Javascript: Part I - Web platform over frameworks](https://alistapart.com/article/responsible-javascript-part-1/)
* [JavaScript Loading Priorities in Chrome](https://addyosmani.com/blog/script-priorities/) - [JavaScript Loading Priorities in Chrome](https://addyosmani.com/blog/script-priorities/)
* [Idle Until Urgent](https://philipwalton.com/articles/idle-until-urgent/) - [Idle Until Urgent](https://philipwalton.com/articles/idle-until-urgent/)
* [Browser painting and considerations for web performance](https://css-tricks.com/browser-painting-and-considerations-for-web-performance/) - [Browser painting and considerations for web performance](https://css-tricks.com/browser-painting-and-considerations-for-web-performance/)
* [The Cost Of JavaScript In 2018](https://medium.com/@addyosmani/the-cost-of-javascript-in-2018-7d8950fbb5d4) ([Video](https://www.youtube.com/watch?v=i5R7giitymk)) - [The Cost Of JavaScript In 2018](https://medium.com/@addyosmani/the-cost-of-javascript-in-2018-7d8950fbb5d4) ([Video](https://www.youtube.com/watch?v=i5R7giitymk))
* [Examining Web Worker Performance](https://www.loxodrome.io/post/web-worker-performance/) - [Examining Web Worker Performance](https://www.loxodrome.io/post/web-worker-performance/)
* [Front-End Performance Checklist](https://github.com/thedaviddias/Front-End-Performance-Checklist) - [Front-End Performance Checklist](https://github.com/thedaviddias/Front-End-Performance-Checklist)
* [jankfree](http://jankfree.org/) - [jankfree](http://jankfree.org/)
* [What forces layout/reflow?](https://gist.github.com/paulirish/5d52fb081b3570c81e3a) - [What forces layout/reflow?](https://gist.github.com/paulirish/5d52fb081b3570c81e3a)
* [Using requestIdleCallback](https://developers.google.com/web/updates/2015/08/using-requestidlecallback) - [Using requestIdleCallback](https://developers.google.com/web/updates/2015/08/using-requestidlecallback)
* [Optimize Javascript Execution](https://developers.google.com/web/fundamentals/performance/rendering/optimize-javascript-execution) - [Optimize Javascript Execution](https://developers.google.com/web/fundamentals/performance/rendering/optimize-javascript-execution)
* [Why Web Developers Need to Care about Interactivity](https://philipwalton.com/articles/why-web-developers-need-to-care-about-interactivity/) - [Why Web Developers Need to Care about Interactivity](https://philipwalton.com/articles/why-web-developers-need-to-care-about-interactivity/)
* [Improving Performance with the Paint Timing API](https://www.sitepen.com/blog/2017/10/06/improving-performance-with-the-paint-timing-api) - [Improving Performance with the Paint Timing API](https://www.sitepen.com/blog/2017/10/06/improving-performance-with-the-paint-timing-api)
* [Deploying ES2015+ Code in Production Today](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) - [Deploying ES2015+ Code in Production Today](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/)
* [Performant Web Animations and Interactions: Achieving 60 FPS](https://blog.algolia.com/performant-web-animations/) - [Performant Web Animations and Interactions: Achieving 60 FPS](https://blog.algolia.com/performant-web-animations/)
* [JavaScript Start-up Performance](https://medium.com/reloading/javascript-start-up-performance-69200f43b201) - [JavaScript Start-up Performance](https://medium.com/reloading/javascript-start-up-performance-69200f43b201)
* [Performant Parallaxing](https://developers.google.com/web/updates/2016/12/performant-parallaxing) - [Performant Parallaxing](https://developers.google.com/web/updates/2016/12/performant-parallaxing)
* [The Anatomy of a Frame](https://aerotwist.com/blog/the-anatomy-of-a-frame/) - [The Anatomy of a Frame](https://aerotwist.com/blog/the-anatomy-of-a-frame/)
* [The future of loading CSS](https://jakearchibald.com/2016/link-in-body/) - [The future of loading CSS](https://jakearchibald.com/2016/link-in-body/)
* [4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them](https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/) - [4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them](https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/)
* [The cost of frameworks](https://aerotwist.com/blog/the-cost-of-frameworks/) - [The cost of frameworks](https://aerotwist.com/blog/the-cost-of-frameworks/)
* [FLIP Your Animations](https://aerotwist.com/blog/flip-your-animations/) - [FLIP Your Animations](https://aerotwist.com/blog/flip-your-animations/)

@ -15,6 +15,5 @@ JavaScript blocks the normal parsing of the HTML document, so when the parser re
- Add `async` (if the script don't rely on other scripts) or `defer` (if the script relies upon or relied upon by an async script) as an attribute to your script tag. - Add `async` (if the script don't rely on other scripts) or `defer` (if the script relies upon or relied upon by an async script) as an attribute to your script tag.
- If you have small scripts, maybe use inline script place above async scripts. - If you have small scripts, maybe use inline script place above async scripts.
- [Remove Render-Blocking JavaScript](https://developers.google.com/speed/docs/insights/BlockingJS) - [Remove Render-Blocking JavaScript](https://developers.google.com/speed/docs/insights/BlockingJS)
- [Defer loading JavaScript](https://varvy.com/pagespeed/defer-loading-javascript.html) - [Defer loading JavaScript](https://varvy.com/pagespeed/defer-loading-javascript.html)

@ -1,7 +1,7 @@
# Preconnect on Fonts # Preconnect on Fonts
```html ```html
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
``` ```
When you arrived on a website, your device needs to find out where your site lives and which server it needs to connect with. Your browser had to contact a DNS server and wait for the lookup complete before fetching the resource (fonts, CSS files...). Prefetches and preconnects allow the browser to lookup the DNS information and start establishing a TCP connection to the server hosting the font file. This provides a performance boost because by the time the browser gets around to parsing the css file with the font information and discovering it needs to request a font file from the server, it will already have pre-resolved the DNS information and have an open connection to the server ready in its connection pool. When you arrived on a website, your device needs to find out where your site lives and which server it needs to connect with. Your browser had to contact a DNS server and wait for the lookup complete before fetching the resource (fonts, CSS files...). Prefetches and preconnects allow the browser to lookup the DNS information and start establishing a TCP connection to the server hosting the font file. This provides a performance boost because by the time the browser gets around to parsing the css file with the font information and discovering it needs to request a font file from the server, it will already have pre-resolved the DNS information and have an open connection to the server ready in its connection pool.

@ -1,29 +1,29 @@
--- ---
jsonUrl: "/jsons/best-practices/frontend-performance.json" jsonUrl: '/jsons/best-practices/frontend-performance.json'
pdfUrl: "/pdfs/best-practices/frontend-performance.pdf" pdfUrl: '/pdfs/best-practices/frontend-performance.pdf'
order: 1 order: 1
briefTitle: "Frontend Performance" briefTitle: 'Frontend Performance'
briefDescription: "Frontend Performance Best Practices" briefDescription: 'Frontend Performance Best Practices'
isNew: true isNew: true
isUpcoming: false isUpcoming: false
title: "Frontend Performance Best Practices" title: 'Frontend Performance Best Practices'
description: "Detailed list of best practices to improve your frontend performance" description: 'Detailed list of best practices to improve your frontend performance'
dimensions: dimensions:
width: 968 width: 968
height: 1270.89 height: 1270.89
schema: schema:
headline: "Frontend Performance Best Practices" headline: 'Frontend Performance Best Practices'
description: "Detailed list of best practices to improve the frontend performance of your website. Each best practice carries further details and how to implement that best practice." description: 'Detailed list of best practices to improve the frontend performance of your website. Each best practice carries further details and how to implement that best practice.'
imageUrl: "https://roadmap.sh/best-practices/frontend-performance.png" imageUrl: 'https://roadmap.sh/best-practices/frontend-performance.png'
datePublished: "2023-01-23" datePublished: '2023-01-23'
dateModified: "2023-01-23" dateModified: '2023-01-23'
seo: seo:
title: "Frontend Performance Best Practices" title: 'Frontend Performance Best Practices'
description: "Detailed list of best practices to improve the frontend performance of your website. Each best practice carries further details and how to implement that best practice." description: 'Detailed list of best practices to improve the frontend performance of your website. Each best practice carries further details and how to implement that best practice.'
keywords: keywords:
- "frontend performance" - 'frontend performance'
- "frontend performance best practices" - 'frontend performance best practices'
- "frontend performance checklist" - 'frontend performance checklist'
- "frontend checklist" - 'frontend checklist'
- "make performant frontends" - 'make performant frontends'
--- ---

@ -1,26 +1,25 @@
--- ---
title: "Asymptotic Notation" title: 'Asymptotic Notation'
description: "Learn the basics of measuring the time and space complexity of algorithms" description: 'Learn the basics of measuring the time and space complexity of algorithms'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Asymptotic Notation - roadmap.sh" title: 'Asymptotic Notation - roadmap.sh'
description: "Learn the basics of measuring the time and space complexity of algorithms" description: 'Learn the basics of measuring the time and space complexity of algorithms'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-04-03 date: 2021-04-03
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
Asymptotic notation is the standard way of measuring the time and space that an algorithm will consume as the input grows. In one of my last guides, I covered "Big-O notation" and a lot of you asked for a similar one for Asymptotic notation. You can find the [previous guide here](/guides/big-o-notation). Asymptotic notation is the standard way of measuring the time and space that an algorithm will consume as the input grows. In one of my last guides, I covered "Big-O notation" and a lot of you asked for a similar one for Asymptotic notation. You can find the [previous guide here](/guides/big-o-notation).
[![Asymptotic Notation](/guides/asymptotic-notation.png)](/guides/asymptotic-notation.png) [![Asymptotic Notation](/guides/asymptotic-notation.png)](/guides/asymptotic-notation.png)

@ -1,24 +1,23 @@
--- ---
title: "Async and Defer Script Loading" title: 'Async and Defer Script Loading'
description: "Learn how to avoid render blocking JavaScript using async and defer scripts." description: 'Learn how to avoid render blocking JavaScript using async and defer scripts.'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Async and Defer Script Loading - roadmap.sh" title: 'Async and Defer Script Loading - roadmap.sh'
description: "Learn how to avoid render blocking JavaScript using async and defer scripts." description: 'Learn how to avoid render blocking JavaScript using async and defer scripts.'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-09-10 date: 2021-09-10
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![Avoid Render Blocking with Async and Defer](/guides/avoid-render-blocking-javascript-with-async-defer.png)](/guides/avoid-render-blocking-javascript-with-async-defer.png) [![Avoid Render Blocking with Async and Defer](/guides/avoid-render-blocking-javascript-with-async-defer.png)](/guides/avoid-render-blocking-javascript-with-async-defer.png)

@ -1,24 +1,23 @@
--- ---
title: "Basic Authentication" title: 'Basic Authentication'
description: "Understand what is basic authentication and how it is implemented" description: 'Understand what is basic authentication and how it is implemented'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Basic Authentication - roadmap.sh" title: 'Basic Authentication - roadmap.sh'
description: "Understand what is basic authentication and how it is implemented" description: 'Understand what is basic authentication and how it is implemented'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-05-19 date: 2021-05-19
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![Basic Authentication](/guides/basic-authentication.png)](/guides/basic-authentication.png) [![Basic Authentication](/guides/basic-authentication.png)](/guides/basic-authentication.png)

@ -1,23 +1,23 @@
--- ---
title: "Basics of Authentication" title: 'Basics of Authentication'
description: "Learn the basics of Authentication and Authorization" description: 'Learn the basics of Authentication and Authorization'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Basics of Authentication - roadmap.sh" title: 'Basics of Authentication - roadmap.sh'
description: "Learn the basics of Authentication and Authorization" description: 'Learn the basics of Authentication and Authorization'
isNew: false isNew: false
type: "textual" type: 'textual'
date: 2022-09-21 date: 2022-09-21
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
Our last video series was about data structures. We looked at the most common data structures, their use cases, pros and cons, and the different operations you could perform on each data structure. Our last video series was about data structures. We looked at the most common data structures, their use cases, pros and cons, and the different operations you could perform on each data structure.
@ -79,6 +79,7 @@ Two-factor authentication is similar to multifactor authentication. The only dif
Next we have the difference between authentication and authorization. This comes up a lot in the interviews, and beginners often confuse them. Next we have the difference between authentication and authorization. This comes up a lot in the interviews, and beginners often confuse them.
### What is Authentication ### What is Authentication
Authentication is the process of verifying the identity. For example, when you enter your credentials at a login screen, the application here identifies you through your credentials. So this is what the authentication is, the process of verifying the identity. Authentication is the process of verifying the identity. For example, when you enter your credentials at a login screen, the application here identifies you through your credentials. So this is what the authentication is, the process of verifying the identity.
In case of an authentication failure, for example, if you enter an invalid username and password, the HTTP response code is "Unauthorized" 401. In case of an authentication failure, for example, if you enter an invalid username and password, the HTTP response code is "Unauthorized" 401.

@ -1,26 +1,25 @@
--- ---
title: "Big-O Notation" title: 'Big-O Notation'
description: "Easy to understand explanation of Big-O notation without any fancy terms" description: 'Easy to understand explanation of Big-O notation without any fancy terms'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Big-O Notation - roadmap.sh" title: 'Big-O Notation - roadmap.sh'
description: "Easy to understand explanation of Big-O notation without any fancy terms" description: 'Easy to understand explanation of Big-O notation without any fancy terms'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-03-15 date: 2021-03-15
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
Big-O notation is the mathematical notation that helps analyse the algorithms to get an idea about how they might perform as the input grows. The image below explains Big-O in a simple way without using any fancy terminology. Big-O notation is the mathematical notation that helps analyse the algorithms to get an idea about how they might perform as the input grows. The image below explains Big-O in a simple way without using any fancy terminology.
[![Big-O Notation](/guides/big-o-notation.png)](/guides/big-o-notation.png) [![Big-O Notation](/guides/big-o-notation.png)](/guides/big-o-notation.png)

@ -1,24 +1,23 @@
--- ---
title: "Character Encodings" title: 'Character Encodings'
description: "Covers the basics of character encodings and explains ASCII vs Unicode" description: 'Covers the basics of character encodings and explains ASCII vs Unicode'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Character Encodings - roadmap.sh" title: 'Character Encodings - roadmap.sh'
description: "Covers the basics of character encodings and explains ASCII vs Unicode" description: 'Covers the basics of character encodings and explains ASCII vs Unicode'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-05-14 date: 2021-05-14
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![Character Encodings](/guides/character-encodings.png)](/guides/character-encodings.png) [![Character Encodings](/guides/character-encodings.png)](/guides/character-encodings.png)

@ -1,26 +1,25 @@
--- ---
title: "What is CI and CD?" title: 'What is CI and CD?'
description: "Learn the basics of CI/CD and how to implement that with GitHub Actions." description: 'Learn the basics of CI/CD and how to implement that with GitHub Actions.'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "What is CI and CD? - roadmap.sh" title: 'What is CI and CD? - roadmap.sh'
description: "Learn the basics of CI/CD and how to implement that with GitHub Actions." description: 'Learn the basics of CI/CD and how to implement that with GitHub Actions.'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-07-09 date: 2021-07-09
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
The image below details the differences between the continuous integration and continuous delivery. Also, here is the [accompanying video on implementing that with GitHub actions](https://www.youtube.com/watch?v=nyKZTKQS_EQ). The image below details the differences between the continuous integration and continuous delivery. Also, here is the [accompanying video on implementing that with GitHub actions](https://www.youtube.com/watch?v=nyKZTKQS_EQ).
[![CI vs CD](/guides/ci-cd.png)](/guides/ci-cd.png) [![CI vs CD](/guides/ci-cd.png)](/guides/ci-cd.png)

@ -1,24 +1,24 @@
--- ---
title: "Consistency Patterns" title: 'Consistency Patterns'
description: "Everything you need to know about Week, Strong and Eventual Consistency" description: 'Everything you need to know about Week, Strong and Eventual Consistency'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Consistency Patterns - roadmap.sh" title: 'Consistency Patterns - roadmap.sh'
description: "Everything you need to know about Week, Strong and Eventual Consistency" description: 'Everything you need to know about Week, Strong and Eventual Consistency'
isNew: true isNew: true
canonicalUrl: "https://cs.fyi/guide/consistency-patterns-week-strong-eventual/" canonicalUrl: 'https://cs.fyi/guide/consistency-patterns-week-strong-eventual/'
type: "textual" type: 'textual'
date: 2023-01-18 date: 2023-01-18
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
Before we talk about the Consistency Patterns, we should know what a distributed system is. Simply put, a distributed system is a system that consists of more than one components, and each component is responsible for one part of the application. Before we talk about the Consistency Patterns, we should know what a distributed system is. Simply put, a distributed system is a system that consists of more than one components, and each component is responsible for one part of the application.
@ -41,9 +41,9 @@ When working with distributed systems, we need to think about managing the data
Consistency patterns refer to the ways in which data is stored and managed in a distributed system and how that data is made available to users and applications. There are three main types of consistency patterns: Consistency patterns refer to the ways in which data is stored and managed in a distributed system and how that data is made available to users and applications. There are three main types of consistency patterns:
* Strong consistency - Strong consistency
* Weak consistency - Weak consistency
* Eventual Consistency - Eventual Consistency
Each of these patterns has its own advantages and disadvantages, and the choice of which pattern to use will depend on the specific requirements of the application or system. Each of these patterns has its own advantages and disadvantages, and the choice of which pattern to use will depend on the specific requirements of the application or system.

@ -1,23 +1,23 @@
--- ---
title: "Design Patterns for Humans" title: 'Design Patterns for Humans'
description: "A language agnostic, ultra-simplified explanation to design patterns" description: 'A language agnostic, ultra-simplified explanation to design patterns'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Design Patterns for Humans - roadmap.sh" title: 'Design Patterns for Humans - roadmap.sh'
description: "A language agnostic, ultra-simplified explanation to design patterns" description: 'A language agnostic, ultra-simplified explanation to design patterns'
isNew: false isNew: false
type: "textual" type: 'textual'
date: 2019-01-23 date: 2019-01-23
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
Design patterns are solutions to recurring problems; **guidelines on how to tackle certain problems**. They are not classes, packages or libraries that you can plug into your application and wait for the magic to happen. These are, rather, guidelines on how to tackle certain problems in certain situations. Design patterns are solutions to recurring problems; **guidelines on how to tackle certain problems**. They are not classes, packages or libraries that you can plug into your application and wait for the magic to happen. These are, rather, guidelines on how to tackle certain problems in certain situations.
@ -43,41 +43,47 @@ Developers, mostly beginners, make the mistake of over-thinking and forcing the
This guide is about Gang of Four (GoF) design patterns, which refers to the four authors of [the book which introduced these design patterns](https://en.wikipedia.org/wiki/Design_Patterns). There are three types of design patterns: This guide is about Gang of Four (GoF) design patterns, which refers to the four authors of [the book which introduced these design patterns](https://en.wikipedia.org/wiki/Design_Patterns). There are three types of design patterns:
* [Creational](#creational-design-patterns) - [Creational](#creational-design-patterns)
* [Structural](#structural-design-patterns) - [Structural](#structural-design-patterns)
* [Behavioral](#behavioral-design-patterns) - [Behavioral](#behavioral-design-patterns)
## Creational Design Patterns ## Creational Design Patterns
In plain words In plain words
> Creational patterns are focused towards how to instantiate an object or group of related objects. > Creational patterns are focused towards how to instantiate an object or group of related objects.
Wikipedia says Wikipedia says
> In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation. > In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation.
There are 6 types of Creational patterns There are 6 types of Creational patterns
* [Simple Factory](#-simple-factory) - [Simple Factory](#-simple-factory)
* [Factory Method](#-factory-method) - [Factory Method](#-factory-method)
* [Abstract Factory](#-abstract-factory) - [Abstract Factory](#-abstract-factory)
* [Builder](#-builder) - [Builder](#-builder)
* [Prototype](#-prototype) - [Prototype](#-prototype)
* [Singleton](#-singleton) - [Singleton](#-singleton)
## 🏠 Simple Factory
🏠 Simple Factory
--------------
Real world example Real world example
> Consider, you are building a house and you need doors. You can either put on your carpenter clothes, bring some wood, glue, nails and all the tools required to build the door and start building it in your house or you can simply call the factory and get the built door delivered to you so that you don't need to learn anything about the door making or to deal with the mess that comes with making it. > Consider, you are building a house and you need doors. You can either put on your carpenter clothes, bring some wood, glue, nails and all the tools required to build the door and start building it in your house or you can simply call the factory and get the built door delivered to you so that you don't need to learn anything about the door making or to deal with the mess that comes with making it.
In plain words In plain words
> Simple factory simply generates an instance for client without exposing any instantiation logic to the client > Simple factory simply generates an instance for client without exposing any instantiation logic to the client
Wikipedia says Wikipedia says
> In object-oriented programming (OOP), a factory is an object for creating other objects – formally a factory is a function or method that returns objects of a varying prototype or class from some method call, which is assumed to be "new". > In object-oriented programming (OOP), a factory is an object for creating other objects – formally a factory is a function or method that returns objects of a varying prototype or class from some method call, which is assumed to be "new".
**Programmatic Example** **Programmatic Example**
First of all we have a door interface and the implementation First of all we have a door interface and the implementation
```php ```php
interface Door interface Door
{ {
@ -107,7 +113,9 @@ class WoodenDoor implements Door
} }
} }
``` ```
Then we have our door factory that makes the door and returns it Then we have our door factory that makes the door and returns it
```php ```php
class DoorFactory class DoorFactory
{ {
@ -117,7 +125,9 @@ class DoorFactory
} }
} }
``` ```
And then it can be used as And then it can be used as
```php ```php
// Make me a door of 100x200 // Make me a door of 100x200
$door = DoorFactory::makeDoor(100, 200); $door = DoorFactory::makeDoor(100, 200);
@ -133,16 +143,18 @@ $door2 = DoorFactory::makeDoor(50, 100);
When creating an object is not just a few assignments and involves some logic, it makes sense to put it in a dedicated factory instead of repeating the same code everywhere. When creating an object is not just a few assignments and involves some logic, it makes sense to put it in a dedicated factory instead of repeating the same code everywhere.
🏭 Factory Method ## 🏭 Factory Method
--------------
Real world example Real world example
> Consider the case of a hiring manager. It is impossible for one person to interview for each of the positions. Based on the job opening, she has to decide and delegate the interview steps to different people. > Consider the case of a hiring manager. It is impossible for one person to interview for each of the positions. Based on the job opening, she has to decide and delegate the interview steps to different people.
In plain words In plain words
> It provides a way to delegate the instantiation logic to child classes. > It provides a way to delegate the instantiation logic to child classes.
Wikipedia says Wikipedia says
> In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor. > In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.
**Programmatic Example** **Programmatic Example**
@ -189,7 +201,9 @@ abstract class HiringManager
} }
``` ```
Now any child can extend it and provide the required interviewer Now any child can extend it and provide the required interviewer
```php ```php
class DevelopmentManager extends HiringManager class DevelopmentManager extends HiringManager
{ {
@ -207,6 +221,7 @@ class MarketingManager extends HiringManager
} }
} }
``` ```
and then it can be used as and then it can be used as
```php ```php
@ -221,16 +236,18 @@ $marketingManager->takeInterview(); // Output: Asking about community building.
Useful when there is some generic processing in a class but the required sub-class is dynamically decided at runtime. Or putting it in other words, when the client doesn't know what exact sub-class it might need. Useful when there is some generic processing in a class but the required sub-class is dynamically decided at runtime. Or putting it in other words, when the client doesn't know what exact sub-class it might need.
🔨 Abstract Factory ## 🔨 Abstract Factory
----------------
Real world example Real world example
> Extending our door example from Simple Factory. Based on your needs you might get a wooden door from a wooden door shop, iron door from an iron shop or a PVC door from the relevant shop. Plus you might need a guy with different kind of specialities to fit the door, for example a carpenter for wooden door, welder for iron door etc. As you can see there is a dependency between the doors now, wooden door needs carpenter, iron door needs a welder etc. > Extending our door example from Simple Factory. Based on your needs you might get a wooden door from a wooden door shop, iron door from an iron shop or a PVC door from the relevant shop. Plus you might need a guy with different kind of specialities to fit the door, for example a carpenter for wooden door, welder for iron door etc. As you can see there is a dependency between the doors now, wooden door needs carpenter, iron door needs a welder etc.
In plain words In plain words
> A factory of factories; a factory that groups the individual but related/dependent factories together without specifying their concrete classes. > A factory of factories; a factory that groups the individual but related/dependent factories together without specifying their concrete classes.
Wikipedia says Wikipedia says
> The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes > The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes
**Programmatic Example** **Programmatic Example**
@ -259,6 +276,7 @@ class IronDoor implements Door
} }
} }
``` ```
Then we have some fitting experts for each door type Then we have some fitting experts for each door type
```php ```php
@ -285,6 +303,7 @@ class Carpenter implements DoorFittingExpert
``` ```
Now we have our abstract factory that would let us make family of related objects i.e. wooden door factory would create a wooden door and wooden door fitting expert and iron door factory would create an iron door and iron door fitting expert Now we have our abstract factory that would let us make family of related objects i.e. wooden door factory would create a wooden door and wooden door fitting expert and iron door factory would create an iron door and iron door fitting expert
```php ```php
interface DoorFactory interface DoorFactory
{ {
@ -320,7 +339,9 @@ class IronDoorFactory implements DoorFactory
} }
} }
``` ```
And then it can be used as And then it can be used as
```php ```php
$woodenFactory = new WoodenDoorFactory(); $woodenFactory = new WoodenDoorFactory();
@ -347,13 +368,17 @@ As you can see the wooden door factory has encapsulated the `carpenter` and the
When there are interrelated dependencies with not-that-simple creation logic involved When there are interrelated dependencies with not-that-simple creation logic involved
## 👷 Builder ## 👷 Builder
Real world example Real world example
> Imagine you are at Hardee's and you order a specific deal, lets say, "Big Hardee" and they hand it over to you without *any questions*; this is the example of simple factory. But there are cases when the creation logic might involve more steps. For example you want a customized Subway deal, you have several options in how your burger is made e.g what bread do you want? what types of sauces would you like? What cheese would you want? etc. In such cases builder pattern comes to the rescue.
> Imagine you are at Hardee's and you order a specific deal, lets say, "Big Hardee" and they hand it over to you without _any questions_; this is the example of simple factory. But there are cases when the creation logic might involve more steps. For example you want a customized Subway deal, you have several options in how your burger is made e.g what bread do you want? what types of sauces would you like? What cheese would you want? etc. In such cases builder pattern comes to the rescue.
In plain words In plain words
> Allows you to create different flavors of an object while avoiding constructor pollution. Useful when there could be several flavors of an object. Or when there are a lot of steps involved in creation of an object. > Allows you to create different flavors of an object while avoiding constructor pollution. Useful when there could be several flavors of an object. Or when there are a lot of steps involved in creation of an object.
Wikipedia says Wikipedia says
> The builder pattern is an object creation software design pattern with the intentions of finding a solution to the telescoping constructor anti-pattern. > The builder pattern is an object creation software design pattern with the intentions of finding a solution to the telescoping constructor anti-pattern.
Having said that let me add a bit about what telescoping constructor anti-pattern is. At one point or the other we have all seen a constructor like below: Having said that let me add a bit about what telescoping constructor anti-pattern is. At one point or the other we have all seen a constructor like below:
@ -438,6 +463,7 @@ class BurgerBuilder
} }
} }
``` ```
And then it can be used as: And then it can be used as:
```php ```php
@ -452,15 +478,18 @@ $burger = (new BurgerBuilder(14))
When there could be several flavors of an object and to avoid the constructor telescoping. The key difference from the factory pattern is that; factory pattern is to be used when the creation is a one step process while builder pattern is to be used when the creation is a multi step process. When there could be several flavors of an object and to avoid the constructor telescoping. The key difference from the factory pattern is that; factory pattern is to be used when the creation is a one step process while builder pattern is to be used when the creation is a multi step process.
🐑 Prototype ## 🐑 Prototype
------------
Real world example Real world example
> Remember dolly? The sheep that was cloned! Lets not get into the details but the key point here is that it is all about cloning > Remember dolly? The sheep that was cloned! Lets not get into the details but the key point here is that it is all about cloning
In plain words In plain words
> Create object based on an existing object through cloning. > Create object based on an existing object through cloning.
Wikipedia says Wikipedia says
> The prototype pattern is a creational design pattern in software development. It is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. > The prototype pattern is a creational design pattern in software development. It is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects.
In short, it allows you to create a copy of an existing object and modify it to your needs, instead of going through the trouble of creating an object from scratch and setting it up. In short, it allows you to create a copy of an existing object and modify it to your needs, instead of going through the trouble of creating an object from scratch and setting it up.
@ -502,7 +531,9 @@ class Sheep
} }
} }
``` ```
Then it can be cloned like below Then it can be cloned like below
```php ```php
$original = new Sheep('Jolly'); $original = new Sheep('Jolly');
echo $original->getName(); // Jolly echo $original->getName(); // Jolly
@ -521,15 +552,18 @@ Also you could use the magic method `__clone` to modify the cloning behavior.
When an object is required that is similar to existing object or when the creation would be expensive as compared to cloning. When an object is required that is similar to existing object or when the creation would be expensive as compared to cloning.
💍 Singleton ## 💍 Singleton
------------
Real world example Real world example
> There can only be one president of a country at a time. The same president has to be brought to action, whenever duty calls. President here is singleton. > There can only be one president of a country at a time. The same president has to be brought to action, whenever duty calls. President here is singleton.
In plain words In plain words
> Ensures that only one object of a particular class is ever created. > Ensures that only one object of a particular class is ever created.
Wikipedia says Wikipedia says
> In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. > In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system.
Singleton pattern is actually considered an anti-pattern and overuse of it should be avoided. It is not necessarily bad and could have some valid use-cases but should be used with caution because it introduces a global state in your application and change to it in one place could affect in the other areas and it could become pretty difficult to debug. The other bad thing about them is it makes your code tightly coupled plus mocking the singleton could be difficult. Singleton pattern is actually considered an anti-pattern and overuse of it should be avoided. It is not necessarily bad and could have some valid use-cases but should be used with caution because it introduces a global state in your application and change to it in one place could affect in the other areas and it could become pretty difficult to debug. The other bad thing about them is it makes your code tightly coupled plus mocking the singleton could be difficult.
@ -537,6 +571,7 @@ Singleton pattern is actually considered an anti-pattern and overuse of it shoul
**Programmatic Example** **Programmatic Example**
To create a singleton, make the constructor private, disable cloning, disable extension and create a static variable to house the instance To create a singleton, make the constructor private, disable cloning, disable extension and create a static variable to house the instance
```php ```php
final class President final class President
{ {
@ -567,7 +602,9 @@ final class President
} }
} }
``` ```
Then in order to use Then in order to use
```php ```php
$president1 = President::getInstance(); $president1 = President::getInstance();
$president2 = President::getInstance(); $president2 = President::getInstance();
@ -576,33 +613,39 @@ var_dump($president1 === $president2); // true
``` ```
## Structural Design Patterns ## Structural Design Patterns
In plain words In plain words
> Structural patterns are mostly concerned with object composition or in other words how the entities can use each other. Or yet another explanation would be, they help in answering "How to build a software component?" > Structural patterns are mostly concerned with object composition or in other words how the entities can use each other. Or yet another explanation would be, they help in answering "How to build a software component?"
Wikipedia says Wikipedia says
> In software engineering, structural design patterns are design patterns that ease the design by identifying a simple way to realize relationships between entities. > In software engineering, structural design patterns are design patterns that ease the design by identifying a simple way to realize relationships between entities.
There are 7 types of structural patterns There are 7 types of structural patterns
* [Adapter](#-adapter) - [Adapter](#-adapter)
* [Bridge](#-bridge) - [Bridge](#-bridge)
* [Composite](#-composite) - [Composite](#-composite)
* [Decorator](#-decorator) - [Decorator](#-decorator)
* [Facade](#-facade) - [Facade](#-facade)
* [Flyweight](#-flyweight) - [Flyweight](#-flyweight)
* [Proxy](#-proxy) - [Proxy](#-proxy)
## 🔌 Adapter
🔌 Adapter
-------
Real world example Real world example
> Consider that you have some pictures in your memory card and you need to transfer them to your computer. In order to transfer them you need some kind of adapter that is compatible with your computer ports so that you can attach memory card to your computer. In this case card reader is an adapter. > Consider that you have some pictures in your memory card and you need to transfer them to your computer. In order to transfer them you need some kind of adapter that is compatible with your computer ports so that you can attach memory card to your computer. In this case card reader is an adapter.
> Another example would be the famous power adapter; a three legged plug can't be connected to a two pronged outlet, it needs to use a power adapter that makes it compatible with the two pronged outlet. > Another example would be the famous power adapter; a three legged plug can't be connected to a two pronged outlet, it needs to use a power adapter that makes it compatible with the two pronged outlet.
> Yet another example would be a translator translating words spoken by one person to another > Yet another example would be a translator translating words spoken by one person to another
In plain words In plain words
> Adapter pattern lets you wrap an otherwise incompatible object in an adapter to make it compatible with another class. > Adapter pattern lets you wrap an otherwise incompatible object in an adapter to make it compatible with another class.
Wikipedia says Wikipedia says
> In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code. > In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code.
**Programmatic Example** **Programmatic Example**
@ -631,7 +674,9 @@ class AsianLion implements Lion
} }
} }
``` ```
And hunter expects any implementation of `Lion` interface to hunt. And hunter expects any implementation of `Lion` interface to hunt.
```php ```php
class Hunter class Hunter
{ {
@ -669,6 +714,7 @@ class WildDogAdapter implements Lion
} }
} }
``` ```
And now the `WildDog` can be used in our game using `WildDogAdapter`. And now the `WildDog` can be used in our game using `WildDogAdapter`.
```php ```php
@ -679,17 +725,20 @@ $hunter = new Hunter();
$hunter->hunt($wildDogAdapter); $hunter->hunt($wildDogAdapter);
``` ```
🚡 Bridge ## 🚡 Bridge
------
Real world example Real world example
> Consider you have a website with different pages and you are supposed to allow the user to change the theme. What would you do? Create multiple copies of each of the pages for each of the themes or would you just create separate theme and load them based on the user's preferences? Bridge pattern allows you to do the second i.e. > Consider you have a website with different pages and you are supposed to allow the user to change the theme. What would you do? Create multiple copies of each of the pages for each of the themes or would you just create separate theme and load them based on the user's preferences? Bridge pattern allows you to do the second i.e.
![With and without the bridge pattern](https://cloud.githubusercontent.com/assets/11269635/23065293/33b7aea0-f515-11e6-983f-98823c9845ee.png) ![With and without the bridge pattern](https://cloud.githubusercontent.com/assets/11269635/23065293/33b7aea0-f515-11e6-983f-98823c9845ee.png)
In Plain Words In Plain Words
> Bridge pattern is about preferring composition over inheritance. Implementation details are pushed from a hierarchy to another object with a separate hierarchy. > Bridge pattern is about preferring composition over inheritance. Implementation details are pushed from a hierarchy to another object with a separate hierarchy.
Wikipedia says Wikipedia says
> The bridge pattern is a design pattern used in software engineering that is meant to "decouple an abstraction from its implementation so that the two can vary independently" > The bridge pattern is a design pattern used in software engineering that is meant to "decouple an abstraction from its implementation so that the two can vary independently"
**Programmatic Example** **Programmatic Example**
@ -733,7 +782,9 @@ class Careers implements WebPage
} }
} }
``` ```
And the separate theme hierarchy And the separate theme hierarchy
```php ```php
interface Theme interface Theme
@ -763,7 +814,9 @@ class AquaTheme implements Theme
} }
} }
``` ```
And both the hierarchies And both the hierarchies
```php ```php
$darkTheme = new DarkTheme(); $darkTheme = new DarkTheme();
@ -777,12 +830,15 @@ echo $careers->getContent(); // "Careers page in Dark Black";
## 🌿 Composite ## 🌿 Composite
Real world example Real world example
> Every organization is composed of employees. Each of the employees has the same features i.e. has a salary, has some responsibilities, may or may not report to someone, may or may not have some subordinates etc. > Every organization is composed of employees. Each of the employees has the same features i.e. has a salary, has some responsibilities, may or may not report to someone, may or may not have some subordinates etc.
In plain words In plain words
> Composite pattern lets clients treat the individual objects in a uniform manner. > Composite pattern lets clients treat the individual objects in a uniform manner.
Wikipedia says Wikipedia says
> In software engineering, the composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects is to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly. > In software engineering, the composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects is to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.
**Programmatic Example** **Programmatic Example**
@ -906,17 +962,18 @@ $organization->addEmployee($jane);
echo "Net salaries: " . $organization->getNetSalaries(); // Net Salaries: 27000 echo "Net salaries: " . $organization->getNetSalaries(); // Net Salaries: 27000
``` ```
☕ Decorator ## ☕ Decorator
-------------
Real world example Real world example
> Imagine you run a car service shop offering multiple services. Now how do you calculate the bill to be charged? You pick one service and dynamically keep adding to it the prices for the provided services till you get the final cost. Here each type of service is a decorator. > Imagine you run a car service shop offering multiple services. Now how do you calculate the bill to be charged? You pick one service and dynamically keep adding to it the prices for the provided services till you get the final cost. Here each type of service is a decorator.
In plain words In plain words
> Decorator pattern lets you dynamically change the behavior of an object at run time by wrapping them in an object of a decorator class. > Decorator pattern lets you dynamically change the behavior of an object at run time by wrapping them in an object of a decorator class.
Wikipedia says Wikipedia says
> In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern. > In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern.
**Programmatic Example** **Programmatic Example**
@ -943,7 +1000,9 @@ class SimpleCoffee implements Coffee
} }
} }
``` ```
We want to make the code extensible to allow options to modify it if required. Lets make some add-ons (decorators) We want to make the code extensible to allow options to modify it if required. Lets make some add-ons (decorators)
```php ```php
class MilkCoffee implements Coffee class MilkCoffee implements Coffee
{ {
@ -1026,16 +1085,18 @@ echo $someCoffee->getCost(); // 20
echo $someCoffee->getDescription(); // Simple Coffee, milk, whip, vanilla echo $someCoffee->getDescription(); // Simple Coffee, milk, whip, vanilla
``` ```
📦 Facade ## 📦 Facade
----------------
Real world example Real world example
> How do you turn on the computer? "Hit the power button" you say! That is what you believe because you are using a simple interface that computer provides on the outside, internally it has to do a lot of stuff to make it happen. This simple interface to the complex subsystem is a facade. > How do you turn on the computer? "Hit the power button" you say! That is what you believe because you are using a simple interface that computer provides on the outside, internally it has to do a lot of stuff to make it happen. This simple interface to the complex subsystem is a facade.
In plain words In plain words
> Facade pattern provides a simplified interface to a complex subsystem. > Facade pattern provides a simplified interface to a complex subsystem.
Wikipedia says Wikipedia says
> A facade is an object that provides a simplified interface to a larger body of code, such as a class library. > A facade is an object that provides a simplified interface to a larger body of code, such as a class library.
**Programmatic Example** **Programmatic Example**
@ -1081,7 +1142,9 @@ class Computer
} }
} }
``` ```
Here we have the facade Here we have the facade
```php ```php
class ComputerFacade class ComputerFacade
{ {
@ -1108,23 +1171,27 @@ class ComputerFacade
} }
} }
``` ```
Now to use the facade Now to use the facade
```php ```php
$computer = new ComputerFacade(new Computer()); $computer = new ComputerFacade(new Computer());
$computer->turnOn(); // Ouch! Beep beep! Loading.. Ready to be used! $computer->turnOn(); // Ouch! Beep beep! Loading.. Ready to be used!
$computer->turnOff(); // Bup bup buzzz! Haah! Zzzzz $computer->turnOff(); // Bup bup buzzz! Haah! Zzzzz
``` ```
🍃 Flyweight ## 🍃 Flyweight
---------
Real world example Real world example
> Did you ever have fresh tea from some stall? They often make more than one cup that you demanded and save the rest for any other customer so to save the resources e.g. gas etc. Flyweight pattern is all about that i.e. sharing. > Did you ever have fresh tea from some stall? They often make more than one cup that you demanded and save the rest for any other customer so to save the resources e.g. gas etc. Flyweight pattern is all about that i.e. sharing.
In plain words In plain words
> It is used to minimize memory usage or computational expenses by sharing as much as possible with similar objects. > It is used to minimize memory usage or computational expenses by sharing as much as possible with similar objects.
Wikipedia says Wikipedia says
> In computer programming, flyweight is a software design pattern. A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory. > In computer programming, flyweight is a software design pattern. A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory.
**Programmatic example** **Programmatic example**
@ -1180,6 +1247,7 @@ class TeaShop
} }
} }
``` ```
And it can be used as below And it can be used as below
```php ```php
@ -1197,13 +1265,17 @@ $shop->serve();
``` ```
## 🎱 Proxy ## 🎱 Proxy
Real world example Real world example
> Have you ever used an access card to go through a door? There are multiple options to open that door i.e. it can be opened either using access card or by pressing a button that bypasses the security. The door's main functionality is to open but there is a proxy added on top of it to add some functionality. Let me better explain it using the code example below. > Have you ever used an access card to go through a door? There are multiple options to open that door i.e. it can be opened either using access card or by pressing a button that bypasses the security. The door's main functionality is to open but there is a proxy added on top of it to add some functionality. Let me better explain it using the code example below.
In plain words In plain words
> Using the proxy pattern, a class represents the functionality of another class. > Using the proxy pattern, a class represents the functionality of another class.
Wikipedia says Wikipedia says
> A proxy, in its most general form, is a class functioning as an interface to something else. A proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes. Use of the proxy can simply be forwarding to the real object, or can provide additional logic. In the proxy extra functionality can be provided, for example caching when operations on the real object are resource intensive, or checking preconditions before operations on the real object are invoked. > A proxy, in its most general form, is a class functioning as an interface to something else. A proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes. Use of the proxy can simply be forwarding to the real object, or can provide additional logic. In the proxy extra functionality can be provided, for example caching when operations on the real object are resource intensive, or checking preconditions before operations on the real object are invoked.
**Programmatic Example** **Programmatic Example**
@ -1230,7 +1302,9 @@ class LabDoor implements Door
} }
} }
``` ```
Then we have a proxy to secure any doors that we want Then we have a proxy to secure any doors that we want
```php ```php
class SecuredDoor class SecuredDoor
{ {
@ -1261,7 +1335,9 @@ class SecuredDoor
} }
} }
``` ```
And here is how it can be used And here is how it can be used
```php ```php
$door = new SecuredDoor(new LabDoor()); $door = new SecuredDoor(new LabDoor());
$door->open('invalid'); // Big no! It ain't possible. $door->open('invalid'); // Big no! It ain't possible.
@ -1269,38 +1345,44 @@ $door->open('invalid'); // Big no! It ain't possible.
$door->open('$ecr@t'); // Opening lab door $door->open('$ecr@t'); // Opening lab door
$door->close(); // Closing lab door $door->close(); // Closing lab door
``` ```
Yet another example would be some sort of data-mapper implementation. For example, I recently made an ODM (Object Data Mapper) for MongoDB using this pattern where I wrote a proxy around mongo classes while utilizing the magic method `__call()`. All the method calls were proxied to the original mongo class and result retrieved was returned as it is but in case of `find` or `findOne` data was mapped to the required class objects and the object was returned instead of `Cursor`. Yet another example would be some sort of data-mapper implementation. For example, I recently made an ODM (Object Data Mapper) for MongoDB using this pattern where I wrote a proxy around mongo classes while utilizing the magic method `__call()`. All the method calls were proxied to the original mongo class and result retrieved was returned as it is but in case of `find` or `findOne` data was mapped to the required class objects and the object was returned instead of `Cursor`.
## Behavioral Design Patterns ## Behavioral Design Patterns
In plain words In plain words
> It is concerned with assignment of responsibilities between the objects. What makes them different from structural patterns is they don't just specify the structure but also outline the patterns for message passing/communication between them. Or in other words, they assist in answering "How to run a behavior in software component?" > It is concerned with assignment of responsibilities between the objects. What makes them different from structural patterns is they don't just specify the structure but also outline the patterns for message passing/communication between them. Or in other words, they assist in answering "How to run a behavior in software component?"
Wikipedia says Wikipedia says
> In software engineering, behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication. > In software engineering, behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication.
There are 10 types of behavioral design patterns There are 10 types of behavioral design patterns
* [Chain of Responsibility](#-chain-of-responsibility) - [Chain of Responsibility](#-chain-of-responsibility)
* [Command](#-command) - [Command](#-command)
* [Iterator](#-iterator) - [Iterator](#-iterator)
* [Mediator](#-mediator) - [Mediator](#-mediator)
* [Memento](#-memento) - [Memento](#-memento)
* [Observer](#-observer) - [Observer](#-observer)
* [Visitor](#-visitor) - [Visitor](#-visitor)
* [Strategy](#-strategy) - [Strategy](#-strategy)
* [State](#-state) - [State](#-state)
* [Template Method](#-template-method) - [Template Method](#-template-method)
## 🔗 Chain of Responsibility ## 🔗 Chain of Responsibility
Real world example Real world example
> For example, you have three payment methods (`A`, `B` and `C`) setup in your account; each having a different amount in it. `A` has 100 USD, `B` has 300 USD and `C` having 1000 USD and the preference for payments is chosen as `A` then `B` then `C`. You try to purchase something that is worth 210 USD. Using Chain of Responsibility, first of all account `A` will be checked if it can make the purchase, if yes purchase will be made and the chain will be broken. If not, request will move forward to account `B` checking for amount if yes chain will be broken otherwise the request will keep forwarding till it finds the suitable handler. Here `A`, `B` and `C` are links of the chain and the whole phenomenon is Chain of Responsibility. > For example, you have three payment methods (`A`, `B` and `C`) setup in your account; each having a different amount in it. `A` has 100 USD, `B` has 300 USD and `C` having 1000 USD and the preference for payments is chosen as `A` then `B` then `C`. You try to purchase something that is worth 210 USD. Using Chain of Responsibility, first of all account `A` will be checked if it can make the purchase, if yes purchase will be made and the chain will be broken. If not, request will move forward to account `B` checking for amount if yes chain will be broken otherwise the request will keep forwarding till it finds the suitable handler. Here `A`, `B` and `C` are links of the chain and the whole phenomenon is Chain of Responsibility.
In plain words In plain words
> It helps building a chain of objects. Request enters from one end and keeps going from object to object till it finds the suitable handler. > It helps building a chain of objects. Request enters from one end and keeps going from object to object till it finds the suitable handler.
Wikipedia says Wikipedia says
> In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. > In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain.
**Programmatic Example** **Programmatic Example**
@ -1394,22 +1476,25 @@ $bank->pay(259);
// Paid 259 using Bitcoin! // Paid 259 using Bitcoin!
``` ```
👮 Command ## 👮 Command
-------
Real world example Real world example
> A generic example would be you ordering food at a restaurant. You (i.e. `Client`) ask the waiter (i.e. `Invoker`) to bring some food (i.e. `Command`) and waiter simply forwards the request to Chef (i.e. `Receiver`) who has the knowledge of what and how to cook. > A generic example would be you ordering food at a restaurant. You (i.e. `Client`) ask the waiter (i.e. `Invoker`) to bring some food (i.e. `Command`) and waiter simply forwards the request to Chef (i.e. `Receiver`) who has the knowledge of what and how to cook.
> Another example would be you (i.e. `Client`) switching on (i.e. `Command`) the television (i.e. `Receiver`) using a remote control (`Invoker`). > Another example would be you (i.e. `Client`) switching on (i.e. `Command`) the television (i.e. `Receiver`) using a remote control (`Invoker`).
In plain words In plain words
> Allows you to encapsulate actions in objects. The key idea behind this pattern is to provide the means to decouple client from receiver. > Allows you to encapsulate actions in objects. The key idea behind this pattern is to provide the means to decouple client from receiver.
Wikipedia says Wikipedia says
> In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to encapsulate all information needed to perform an action or trigger an event at a later time. This information includes the method name, the object that owns the method and values for the method parameters. > In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to encapsulate all information needed to perform an action or trigger an event at a later time. This information includes the method name, the object that owns the method and values for the method parameters.
**Programmatic Example** **Programmatic Example**
First of all we have the receiver that has the implementation of every action that could be performed First of all we have the receiver that has the implementation of every action that could be performed
```php ```php
// Receiver // Receiver
class Bulb class Bulb
@ -1425,7 +1510,9 @@ class Bulb
} }
} }
``` ```
then we have an interface that each of the commands are going to implement and then we have a set of commands then we have an interface that each of the commands are going to implement and then we have a set of commands
```php ```php
interface Command interface Command
{ {
@ -1485,7 +1572,9 @@ class TurnOff implements Command
} }
} }
``` ```
Then we have an `Invoker` with whom the client will interact to process any commands Then we have an `Invoker` with whom the client will interact to process any commands
```php ```php
// Invoker // Invoker
class RemoteControl class RemoteControl
@ -1496,7 +1585,9 @@ class RemoteControl
} }
} }
``` ```
Finally let's see how we can use it in our client Finally let's see how we can use it in our client
```php ```php
$bulb = new Bulb(); $bulb = new Bulb();
@ -1510,16 +1601,18 @@ $remote->submit($turnOff); // Darkness!
Command pattern can also be used to implement a transaction based system. Where you keep maintaining the history of commands as soon as you execute them. If the final command is successfully executed, all good otherwise just iterate through the history and keep executing the `undo` on all the executed commands. Command pattern can also be used to implement a transaction based system. Where you keep maintaining the history of commands as soon as you execute them. If the final command is successfully executed, all good otherwise just iterate through the history and keep executing the `undo` on all the executed commands.
➿ Iterator ## ➿ Iterator
--------
Real world example Real world example
> An old radio set will be a good example of iterator, where user could start at some channel and then use next or previous buttons to go through the respective channels. Or take an example of MP3 player or a TV set where you could press the next and previous buttons to go through the consecutive channels or in other words they all provide an interface to iterate through the respective channels, songs or radio stations. > An old radio set will be a good example of iterator, where user could start at some channel and then use next or previous buttons to go through the respective channels. Or take an example of MP3 player or a TV set where you could press the next and previous buttons to go through the consecutive channels or in other words they all provide an interface to iterate through the respective channels, songs or radio stations.
In plain words In plain words
> It presents a way to access the elements of an object without exposing the underlying presentation. > It presents a way to access the elements of an object without exposing the underlying presentation.
Wikipedia says Wikipedia says
> In object-oriented programming, the iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container's elements. The iterator pattern decouples algorithms from containers; in some cases, algorithms are necessarily container-specific and thus cannot be decoupled. > In object-oriented programming, the iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container's elements. The iterator pattern decouples algorithms from containers; in some cases, algorithms are necessarily container-specific and thus cannot be decoupled.
**Programmatic example** **Programmatic example**
@ -1542,6 +1635,7 @@ class RadioStation
} }
} }
``` ```
Then we have our iterator Then we have our iterator
```php ```php
@ -1600,7 +1694,9 @@ class StationList implements Countable, Iterator
} }
} }
``` ```
And then it can be used as And then it can be used as
```php ```php
$stationList = new StationList(); $stationList = new StationList();
@ -1616,16 +1712,18 @@ foreach($stationList as $station) {
$stationList->removeStation(new RadioStation(89)); // Will remove station 89 $stationList->removeStation(new RadioStation(89)); // Will remove station 89
``` ```
👽 Mediator ## 👽 Mediator
--------
Real world example Real world example
> A general example would be when you talk to someone on your mobile phone, there is a network provider sitting between you and them and your conversation goes through it instead of being directly sent. In this case network provider is mediator. > A general example would be when you talk to someone on your mobile phone, there is a network provider sitting between you and them and your conversation goes through it instead of being directly sent. In this case network provider is mediator.
In plain words In plain words
> Mediator pattern adds a third party object (called mediator) to control the interaction between two objects (called colleagues). It helps reduce the coupling between the classes communicating with each other. Because now they don't need to have the knowledge of each other's implementation. > Mediator pattern adds a third party object (called mediator) to control the interaction between two objects (called colleagues). It helps reduce the coupling between the classes communicating with each other. Because now they don't need to have the knowledge of each other's implementation.
Wikipedia says Wikipedia says
> In software engineering, the mediator pattern defines an object that encapsulates how a set of objects interact. This pattern is considered to be a behavioral pattern due to the way it can alter the program's running behavior. > In software engineering, the mediator pattern defines an object that encapsulates how a set of objects interact. This pattern is considered to be a behavioral pattern due to the way it can alter the program's running behavior.
**Programmatic Example** **Programmatic Example**
@ -1654,6 +1752,7 @@ class ChatRoom implements ChatRoomMediator
``` ```
Then we have our users i.e. colleagues Then we have our users i.e. colleagues
```php ```php
class User { class User {
protected $name; protected $name;
@ -1673,7 +1772,9 @@ class User {
} }
} }
``` ```
And the usage And the usage
```php ```php
$mediator = new ChatRoom(); $mediator = new ChatRoom();
@ -1688,15 +1789,18 @@ $jane->send('Hey!');
// Feb 14, 10:58 [Jane]: Hey! // Feb 14, 10:58 [Jane]: Hey!
``` ```
💾 Memento ## 💾 Memento
-------
Real world example Real world example
> Take the example of calculator (i.e. originator), where whenever you perform some calculation the last calculation is saved in memory (i.e. memento) so that you can get back to it and maybe get it restored using some action buttons (i.e. caretaker). > Take the example of calculator (i.e. originator), where whenever you perform some calculation the last calculation is saved in memory (i.e. memento) so that you can get back to it and maybe get it restored using some action buttons (i.e. caretaker).
In plain words In plain words
> Memento pattern is about capturing and storing the current state of an object in a manner that it can be restored later on in a smooth manner. > Memento pattern is about capturing and storing the current state of an object in a manner that it can be restored later on in a smooth manner.
Wikipedia says Wikipedia says
> The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). > The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback).
Usually useful when you need to provide some sort of undo functionality. Usually useful when you need to provide some sort of undo functionality.
@ -1777,20 +1881,24 @@ $editor->restore($saved);
$editor->getContent(); // This is the first sentence. This is second. $editor->getContent(); // This is the first sentence. This is second.
``` ```
😎 Observer ## 😎 Observer
--------
Real world example Real world example
> A good example would be the job seekers where they subscribe to some job posting site and they are notified whenever there is a matching job opportunity. > A good example would be the job seekers where they subscribe to some job posting site and they are notified whenever there is a matching job opportunity.
In plain words In plain words
> Defines a dependency between objects so that whenever an object changes its state, all its dependents are notified. > Defines a dependency between objects so that whenever an object changes its state, all its dependents are notified.
Wikipedia says Wikipedia says
> The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. > The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
**Programmatic example** **Programmatic example**
Translating our example from above. First of all we have job seekers that need to be notified for a job posting Translating our example from above. First of all we have job seekers that need to be notified for a job posting
```php ```php
class JobPost class JobPost
{ {
@ -1823,7 +1931,9 @@ class JobSeeker implements Observer
} }
} }
``` ```
Then we have our job postings to which the job seekers will subscribe Then we have our job postings to which the job seekers will subscribe
```php ```php
class EmploymentAgency implements Observable class EmploymentAgency implements Observable
{ {
@ -1847,7 +1957,9 @@ class EmploymentAgency implements Observable
} }
} }
``` ```
Then it can be used as Then it can be used as
```php ```php
// Create subscribers // Create subscribers
$johnDoe = new JobSeeker('John Doe'); $johnDoe = new JobSeeker('John Doe');
@ -1866,15 +1978,18 @@ $jobPostings->addJob(new JobPost('Software Engineer'));
// Hi Jane Doe! New job posted: Software Engineer // Hi Jane Doe! New job posted: Software Engineer
``` ```
🏃 Visitor ## 🏃 Visitor
-------
Real world example Real world example
> Consider someone visiting Dubai. They just need a way (i.e. visa) to enter Dubai. After arrival, they can come and visit any place in Dubai on their own without having to ask for permission or to do some leg work in order to visit any place here; just let them know of a place and they can visit it. Visitor pattern lets you do just that, it helps you add places to visit so that they can visit as much as they can without having to do any legwork. > Consider someone visiting Dubai. They just need a way (i.e. visa) to enter Dubai. After arrival, they can come and visit any place in Dubai on their own without having to ask for permission or to do some leg work in order to visit any place here; just let them know of a place and they can visit it. Visitor pattern lets you do just that, it helps you add places to visit so that they can visit as much as they can without having to do any legwork.
In plain words In plain words
> Visitor pattern lets you add further operations to objects without having to modify them. > Visitor pattern lets you add further operations to objects without having to modify them.
Wikipedia says Wikipedia says
> In object-oriented programming and software engineering, the visitor design pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying those structures. It is one way to follow the open/closed principle. > In object-oriented programming and software engineering, the visitor design pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying those structures. It is one way to follow the open/closed principle.
**Programmatic example** **Programmatic example**
@ -1896,7 +2011,9 @@ interface AnimalOperation
public function visitDolphin(Dolphin $dolphin); public function visitDolphin(Dolphin $dolphin);
} }
``` ```
Then we have our implementations for the animals Then we have our implementations for the animals
```php ```php
class Monkey implements Animal class Monkey implements Animal
{ {
@ -1937,7 +2054,9 @@ class Dolphin implements Animal
} }
} }
``` ```
Let's implement our visitor Let's implement our visitor
```php ```php
class Speak implements AnimalOperation class Speak implements AnimalOperation
{ {
@ -1959,6 +2078,7 @@ class Speak implements AnimalOperation
``` ```
And then it can be used as And then it can be used as
```php ```php
$monkey = new Monkey(); $monkey = new Monkey();
$lion = new Lion(); $lion = new Lion();
@ -1970,6 +2090,7 @@ $monkey->accept($speak); // Ooh oo aa aa!
$lion->accept($speak); // Roaaar! $lion->accept($speak); // Roaaar!
$dolphin->accept($speak); // Tuut tutt tuutt! $dolphin->accept($speak); // Tuut tutt tuutt!
``` ```
We could have done this simply by having an inheritance hierarchy for the animals but then we would have to modify the animals whenever we would have to add new actions to animals. But now we will not have to change them. For example, let's say we are asked to add the jump behavior to the animals, we can simply add that by creating a new visitor i.e. We could have done this simply by having an inheritance hierarchy for the animals but then we would have to modify the animals whenever we would have to add new actions to animals. But now we will not have to change them. For example, let's say we are asked to add the jump behavior to the animals, we can simply add that by creating a new visitor i.e.
```php ```php
@ -1991,7 +2112,9 @@ class Jump implements AnimalOperation
} }
} }
``` ```
And for the usage And for the usage
```php ```php
$jump = new Jump(); $jump = new Jump();
@ -2005,16 +2128,18 @@ $dolphin->accept($speak); // Tuut tutt tuutt!
$dolphin->accept($jump); // Walked on water a little and disappeared $dolphin->accept($jump); // Walked on water a little and disappeared
``` ```
💡 Strategy ## 💡 Strategy
--------
Real world example Real world example
> Consider the example of sorting, we implemented bubble sort but the data started to grow and bubble sort started getting very slow. In order to tackle this we implemented Quick sort. But now although the quick sort algorithm was doing better for large datasets, it was very slow for smaller datasets. In order to handle this we implemented a strategy where for small datasets, bubble sort will be used and for larger, quick sort. > Consider the example of sorting, we implemented bubble sort but the data started to grow and bubble sort started getting very slow. In order to tackle this we implemented Quick sort. But now although the quick sort algorithm was doing better for large datasets, it was very slow for smaller datasets. In order to handle this we implemented a strategy where for small datasets, bubble sort will be used and for larger, quick sort.
In plain words In plain words
> Strategy pattern allows you to switch the algorithm or strategy based upon the situation. > Strategy pattern allows you to switch the algorithm or strategy based upon the situation.
Wikipedia says Wikipedia says
> In computer programming, the strategy pattern (also known as the policy pattern) is a behavioural software design pattern that enables an algorithm's behavior to be selected at runtime. > In computer programming, the strategy pattern (also known as the policy pattern) is a behavioural software design pattern that enables an algorithm's behavior to be selected at runtime.
**Programmatic example** **Programmatic example**
@ -2051,6 +2176,7 @@ class QuickSortStrategy implements SortStrategy
``` ```
And then we have our client that is going to use any strategy And then we have our client that is going to use any strategy
```php ```php
class Sorter class Sorter
{ {
@ -2067,7 +2193,9 @@ class Sorter
} }
} }
``` ```
And it can be used as And it can be used as
```php ```php
$dataset = [1, 5, 4, 3, 2, 8]; $dataset = [1, 5, 4, 3, 2, 8];
@ -2078,15 +2206,18 @@ $sorter = new Sorter(new QuickSortStrategy());
$sorter->sort($dataset); // Output : Sorting using quick sort $sorter->sort($dataset); // Output : Sorting using quick sort
``` ```
💢 State ## 💢 State
-----
Real world example Real world example
> Imagine you are using some drawing application, you choose the paint brush to draw. Now the brush changes its behavior based on the selected color i.e. if you have chosen red color it will draw in red, if blue then it will be in blue etc. > Imagine you are using some drawing application, you choose the paint brush to draw. Now the brush changes its behavior based on the selected color i.e. if you have chosen red color it will draw in red, if blue then it will be in blue etc.
In plain words In plain words
> It lets you change the behavior of a class when the state changes. > It lets you change the behavior of a class when the state changes.
Wikipedia says Wikipedia says
> The state pattern is a behavioral software design pattern that implements a state machine in an object-oriented way. With the state pattern, a state machine is implemented by implementing each individual state as a derived class of the state pattern interface, and implementing state transitions by invoking methods defined by the pattern's superclass. > The state pattern is a behavioral software design pattern that implements a state machine in an object-oriented way. With the state pattern, a state machine is implemented by implementing each individual state as a derived class of the state pattern interface, and implementing state transitions by invoking methods defined by the pattern's superclass.
> The state pattern can be interpreted as a strategy pattern which is able to switch the current strategy through invocations of methods defined in the pattern's interface. > The state pattern can be interpreted as a strategy pattern which is able to switch the current strategy through invocations of methods defined in the pattern's interface.
@ -2126,7 +2257,9 @@ class DefaultText implements WritingState
} }
} }
``` ```
Then we have our editor Then we have our editor
```php ```php
class TextEditor class TextEditor
{ {
@ -2148,7 +2281,9 @@ class TextEditor
} }
} }
``` ```
And then it can be used as And then it can be used as
```php ```php
$editor = new TextEditor(new DefaultText()); $editor = new TextEditor(new DefaultText());
@ -2172,11 +2307,12 @@ $editor->type('Fifth line');
// fifth line // fifth line
``` ```
📒 Template Method ## 📒 Template Method
---------------
Real world example Real world example
> Suppose we are getting some house built. The steps for building might look like > Suppose we are getting some house built. The steps for building might look like
>
> - Prepare the base of house > - Prepare the base of house
> - Build the walls > - Build the walls
> - Add roof > - Add roof
@ -2185,9 +2321,11 @@ Real world example
> The order of these steps could never be changed i.e. you can't build the roof before building the walls etc but each of the steps could be modified for example walls can be made of wood or polyester or stone. > The order of these steps could never be changed i.e. you can't build the roof before building the walls etc but each of the steps could be modified for example walls can be made of wood or polyester or stone.
In plain words In plain words
> Template method defines the skeleton of how a certain algorithm could be performed, but defers the implementation of those steps to the children classes. > Template method defines the skeleton of how a certain algorithm could be performed, but defers the implementation of those steps to the children classes.
Wikipedia says Wikipedia says
> In software engineering, the template method pattern is a behavioral design pattern that defines the program skeleton of an algorithm in an operation, deferring some steps to subclasses. It lets one redefine certain steps of an algorithm without changing the algorithm's structure. > In software engineering, the template method pattern is a behavioral design pattern that defines the program skeleton of an algorithm in an operation, deferring some steps to subclasses. It lets one redefine certain steps of an algorithm without changing the algorithm's structure.
**Programmatic Example** **Programmatic Example**
@ -2195,6 +2333,7 @@ Wikipedia says
Imagine we have a build tool that helps us test, lint, build, generate build reports (i.e. code coverage reports, linting report etc) and deploy our app on the test server. Imagine we have a build tool that helps us test, lint, build, generate build reports (i.e. code coverage reports, linting report etc) and deploy our app on the test server.
First of all we have our base class that specifies the skeleton for the build algorithm First of all we have our base class that specifies the skeleton for the build algorithm
```php ```php
abstract class Builder abstract class Builder
{ {
@ -2264,6 +2403,7 @@ class IosBuilder extends Builder
} }
} }
``` ```
And then it can be used as And then it can be used as
```php ```php

@ -1,24 +1,23 @@
--- ---
title: "DHCP in One Picture" title: 'DHCP in One Picture'
description: "Here is what happens when a new device joins the network." description: 'Here is what happens when a new device joins the network.'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "DHCP in One Picture - roadmap.sh" title: 'DHCP in One Picture - roadmap.sh'
description: "Here is what happens when a new device joins the network." description: 'Here is what happens when a new device joins the network.'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-04-28 date: 2021-04-28
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![DHCP in One Picture](/guides/dhcp.png)](/guides/dhcp.png) [![DHCP in One Picture](/guides/dhcp.png)](/guides/dhcp.png)

@ -1,23 +1,23 @@
--- ---
title: "DNS in One Picture" title: 'DNS in One Picture'
description: "Quick illustrative guide on how a website is found on the internet." description: 'Quick illustrative guide on how a website is found on the internet.'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "DNS in One Picture - roadmap.sh" title: 'DNS in One Picture - roadmap.sh'
description: "Quick illustrative guide on how a website is found on the internet." description: 'Quick illustrative guide on how a website is found on the internet.'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2018-12-04 date: 2018-12-04
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
DNS or Domain Name System is one of the fundamental blocks of the internet. As a developer, you should have at-least the basic understanding of how it works. This article is a brief introduction to what is DNS and how it works. DNS or Domain Name System is one of the fundamental blocks of the internet. As a developer, you should have at-least the basic understanding of how it works. This article is a brief introduction to what is DNS and how it works.

@ -1,63 +1,72 @@
--- ---
title: "Brief History of JavaScript" title: 'Brief History of JavaScript'
description: "How JavaScript was introduced and evolved over the years" description: 'How JavaScript was introduced and evolved over the years'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Brief History of JavaScript - roadmap.sh" title: 'Brief History of JavaScript - roadmap.sh'
description: "How JavaScript was introduced and evolved over the years" description: 'How JavaScript was introduced and evolved over the years'
isNew: false isNew: false
type: "textual" type: 'textual'
date: 2017-10-28 date: 2017-10-28
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
Around 10 years ago, Jeff Atwood (the founder of stackoverflow) made a case that JavaScript is going to be the future and he coined the “Atwood Law” which states that *Any application that can be written in JavaScript will eventually be written in JavaScript*. Fast-forward to today, 10 years later, if you look at it it rings truer than ever. JavaScript is continuing to gain more and more adoption. Around 10 years ago, Jeff Atwood (the founder of stackoverflow) made a case that JavaScript is going to be the future and he coined the “Atwood Law” which states that _Any application that can be written in JavaScript will eventually be written in JavaScript_. Fast-forward to today, 10 years later, if you look at it it rings truer than ever. JavaScript is continuing to gain more and more adoption.
### JavaScript is announced ### JavaScript is announced
JavaScript was initially created by [Brendan Eich](https://twitter.com/BrendanEich) of NetScape and was first announced in a press release by Netscape in 1995. It has a bizarre history of naming; initially it was named `Mocha` by the creator, which was later renamed to `LiveScript`. In 1996, about a year later after the release, NetScape decided to rename it to be `JavaScript` with hopes of capitalizing on the Java community (although JavaScript did not have any relationship with Java) and released Netscape 2.0 with the official support of JavaScript. JavaScript was initially created by [Brendan Eich](https://twitter.com/BrendanEich) of NetScape and was first announced in a press release by Netscape in 1995. It has a bizarre history of naming; initially it was named `Mocha` by the creator, which was later renamed to `LiveScript`. In 1996, about a year later after the release, NetScape decided to rename it to be `JavaScript` with hopes of capitalizing on the Java community (although JavaScript did not have any relationship with Java) and released Netscape 2.0 with the official support of JavaScript.
### ES1, ES2 and ES3 ### ES1, ES2 and ES3
In 1996, Netscape decided to submit it to [ECMA International](https://en.wikipedia.org/wiki/Ecma_International) with the hopes of getting it standardized. First edition of the standard specification was released in 1997 and the language was standardized. After the initial release, `ECMAScript` was continued to be worked upon and in no-time two more versions were released ECMAScript 2 in 1998 and ECMAScript 3 in 1999. In 1996, Netscape decided to submit it to [ECMA International](https://en.wikipedia.org/wiki/Ecma_International) with the hopes of getting it standardized. First edition of the standard specification was released in 1997 and the language was standardized. After the initial release, `ECMAScript` was continued to be worked upon and in no-time two more versions were released ECMAScript 2 in 1998 and ECMAScript 3 in 1999.
### Decade of Silence and ES4 ### Decade of Silence and ES4
After the release of ES3 in 1999, there was a complete silence for a decade and no changes were made to the official standard. There was some work on the fourth edition in the initial days; some of the features that were being discussed included classes, modules, static typings, destructuring etc. It was being targeted to be released by 2008 but was abandoned due to political differences concerning language complexity. However, the vendors kept introducing the extensions to the language and the developers were left scratching their heads — adding polyfills to battle compatibility issues between different browsers. After the release of ES3 in 1999, there was a complete silence for a decade and no changes were made to the official standard. There was some work on the fourth edition in the initial days; some of the features that were being discussed included classes, modules, static typings, destructuring etc. It was being targeted to be released by 2008 but was abandoned due to political differences concerning language complexity. However, the vendors kept introducing the extensions to the language and the developers were left scratching their heads — adding polyfills to battle compatibility issues between different browsers.
### From silence to ES5 ### From silence to ES5
Google, Microsoft, Yahoo and other disputers of ES4 came together and decided to work on a less ambitious update to ES3 tentatively named ES3.1. But the teams were still fighting about what to include from ES4 and what not. Finally, in 2009 ES5 was released mainly focusing on fixing the compatibility and security issues etc. But there wasn’t much of a splash in the water — it took ages for the vendors to incorporate the standards and many developers were still using ES3 without being aware of the “modern” standards. Google, Microsoft, Yahoo and other disputers of ES4 came together and decided to work on a less ambitious update to ES3 tentatively named ES3.1. But the teams were still fighting about what to include from ES4 and what not. Finally, in 2009 ES5 was released mainly focusing on fixing the compatibility and security issues etc. But there wasn’t much of a splash in the water — it took ages for the vendors to incorporate the standards and many developers were still using ES3 without being aware of the “modern” standards.
### Release of ES6 — ECMAScript 2015 ### Release of ES6 — ECMAScript 2015
After a few years of the release of ES5, things started to change, TC39 (the committee under ECMA international responsible for ECMAScript standardization) kept working on the next version of ECMAScript (ES6) which was originally named ES Harmony, before being eventually released with the name ES2015. ES2015 adds significant features and syntactic sugar to allow writing complex applications. Some of the features that ES6 has to offer, include Classes, Modules, Arrows, Enhanced object literals, Template strings, Destructuring, Default param values + rest + spread, Let and Const, Iterators + for..of, Generators, Maps + Sets, Proxies, Symbols, Promises, math + number + string + array + object APIs [etc](http://es6-features.org/#Constants) After a few years of the release of ES5, things started to change, TC39 (the committee under ECMA international responsible for ECMAScript standardization) kept working on the next version of ECMAScript (ES6) which was originally named ES Harmony, before being eventually released with the name ES2015. ES2015 adds significant features and syntactic sugar to allow writing complex applications. Some of the features that ES6 has to offer, include Classes, Modules, Arrows, Enhanced object literals, Template strings, Destructuring, Default param values + rest + spread, Let and Const, Iterators + for..of, Generators, Maps + Sets, Proxies, Symbols, Promises, math + number + string + array + object APIs [etc](http://es6-features.org/#Constants)
Browser support for ES6 is still scarce but everything that ES6 has to offer is still available to developers by transpiling the ES6 code to ES5. With the release of 6th version of ECMAScript, TC39 decided to move to yearly model of releasing updates to ECMAScript so to make sure that the new features are added as soon as they are approved and we don’t have to wait for the full specification to be drafted and approved — thus 6th version of ECMAScript was renamed as ECMAScript 2015 or ES2015 before the release in June 2015. And the next versions of ECMAScript were decided to published in June of every year. Browser support for ES6 is still scarce but everything that ES6 has to offer is still available to developers by transpiling the ES6 code to ES5. With the release of 6th version of ECMAScript, TC39 decided to move to yearly model of releasing updates to ECMAScript so to make sure that the new features are added as soon as they are approved and we don’t have to wait for the full specification to be drafted and approved — thus 6th version of ECMAScript was renamed as ECMAScript 2015 or ES2015 before the release in June 2015. And the next versions of ECMAScript were decided to published in June of every year.
### Release of ES7 — ECMAScript 2016 ### Release of ES7 — ECMAScript 2016
In June 2016, seventh version of ECMAScript was released. As ECMAScript has been moved to an yearly release model, ECMAScript 2016 (ES2016) comparatively did not have much to offer. ES2016 includes just two new features In June 2016, seventh version of ECMAScript was released. As ECMAScript has been moved to an yearly release model, ECMAScript 2016 (ES2016) comparatively did not have much to offer. ES2016 includes just two new features
* Exponentiation operator `**` - Exponentiation operator `**`
* `Array.prototype.includes` - `Array.prototype.includes`
### Release of ES8 — ECMAScript 2017 ### Release of ES8 — ECMAScript 2017
The eighth version of ECMAScript was released in June 2017. The key highlight of ES8 was the addition of async functions. Here is the list of new features in ES8 The eighth version of ECMAScript was released in June 2017. The key highlight of ES8 was the addition of async functions. Here is the list of new features in ES8
* `Object.values()` and `Object.entries()` - `Object.values()` and `Object.entries()`
* String padding i.e. `String.prototype.padEnd()` and `String.prototype.padStart()` - String padding i.e. `String.prototype.padEnd()` and `String.prototype.padStart()`
* `Object.getOwnPropertyDescriptors` - `Object.getOwnPropertyDescriptors`
* Trailing commas in function parameter lists and calls - Trailing commas in function parameter lists and calls
* Async functions - Async functions
### What is ESNext then? ### What is ESNext then?
ESNext is a dynamic name that refers to whatever the current version of ECMAScript is at the given time. For example, at the time of this writing `ES2017` or `ES8` is `ESNext`. ESNext is a dynamic name that refers to whatever the current version of ECMAScript is at the given time. For example, at the time of this writing `ES2017` or `ES8` is `ESNext`.
### What does the future hold? ### What does the future hold?
Since the release of ES6, [TC39](https://github.com/tc39) has quite streamlined their process. TC39 operates through a Github organization now and there are [several proposals](https://github.com/tc39/proposals) for new features or syntax to be added to the next versions of ECMAScript. Any one can go ahead and [submit a proposal](https://github.com/tc39/proposals) thus resulting in increasing the participation from the community. Every proposal goes through [four stages of maturity](https://tc39.github.io/process-document/) before it makes it into the specification. Since the release of ES6, [TC39](https://github.com/tc39) has quite streamlined their process. TC39 operates through a Github organization now and there are [several proposals](https://github.com/tc39/proposals) for new features or syntax to be added to the next versions of ECMAScript. Any one can go ahead and [submit a proposal](https://github.com/tc39/proposals) thus resulting in increasing the participation from the community. Every proposal goes through [four stages of maturity](https://tc39.github.io/process-document/) before it makes it into the specification.
And that about wraps it up. Feel free to leave your feedback in the comments section below. Also here are the links to original language specifications [ES6](https://www.ecma-international.org/ecma-262/6.0/), [ES7](https://www.ecma-international.org/ecma-262/7.0/) and [ES8](https://www.ecma-international.org/ecma-262/8.0/). And that about wraps it up. Feel free to leave your feedback in the comments section below. Also here are the links to original language specifications [ES6](https://www.ecma-international.org/ecma-262/6.0/), [ES7](https://www.ecma-international.org/ecma-262/7.0/) and [ES8](https://www.ecma-international.org/ecma-262/8.0/).

@ -1,23 +1,23 @@
--- ---
title: "Jump Servers: What, Why and How" title: 'Jump Servers: What, Why and How'
description: "Learn what is a Jump Server and how to set it up for SSH access." description: 'Learn what is a Jump Server and how to set it up for SSH access.'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Jump Servers: What, Why and How - roadmap.sh" title: 'Jump Servers: What, Why and How - roadmap.sh'
description: "Learn what is a Jump Server and how to set it up for SSH access." description: 'Learn what is a Jump Server and how to set it up for SSH access.'
isNew: true isNew: true
type: "visual" type: 'visual'
date: 2023-03-20 date: 2023-03-20
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
Given below is the demonstration of a sample production environment for a web application that consists of two different components, application server and database server. Given below is the demonstration of a sample production environment for a web application that consists of two different components, application server and database server.

@ -1,23 +1,23 @@
--- ---
title: "HTTP Basic Authentication" title: 'HTTP Basic Authentication'
description: "Learn what is HTTP Basic Authentication and how to implement it in Node.js" description: 'Learn what is HTTP Basic Authentication and how to implement it in Node.js'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "HTTP Basic Authentication - roadmap.sh" title: 'HTTP Basic Authentication - roadmap.sh'
description: "Learn what is HTTP Basic Authentication and how to implement it in Node.js" description: 'Learn what is HTTP Basic Authentication and how to implement it in Node.js'
isNew: false isNew: false
type: "textual" type: 'textual'
date: 2022-10-03 date: 2022-10-03
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
Our last guide was about the [basics of authentication](/guides/basics-of-authentication), where we discussed authentication, authorization, types of authentication, authentication factors, authentication strategies, and so on. Our last guide was about the [basics of authentication](/guides/basics-of-authentication), where we discussed authentication, authorization, types of authentication, authentication factors, authentication strategies, and so on.
@ -27,17 +27,19 @@ In this guide today, we will be learning about basic authentication, and we will
<iframe class="w-full aspect-video mb-5" src="https://www.youtube.com/embed/mwccHwUn7Gc" title="HTTP Basic Authentication"></iframe> <iframe class="w-full aspect-video mb-5" src="https://www.youtube.com/embed/mwccHwUn7Gc" title="HTTP Basic Authentication"></iframe>
## What is Basic Authentication? ## What is Basic Authentication?
Given the name "Basic Authentication", you should not confuse Basic Authentication with the standard username and password authentication. Basic authentication is a part of the HTTP specification, and the details can be [found in the RFC7617](https://www.rfc-editor.org/rfc/rfc7617.html). Given the name "Basic Authentication", you should not confuse Basic Authentication with the standard username and password authentication. Basic authentication is a part of the HTTP specification, and the details can be [found in the RFC7617](https://www.rfc-editor.org/rfc/rfc7617.html).
Because it is a part of the HTTP specifications, all the browsers have native support for "HTTP Basic Authentication". Given below is the screenshot from the implementation in Google Chrome. Because it is a part of the HTTP specifications, all the browsers have native support for "HTTP Basic Authentication". Given below is the screenshot from the implementation in Google Chrome.
![Chrome Basic Authentication](/guides/basic-authentication/chrome-basic-auth.png) ![Chrome Basic Authentication](/guides/basic-authentication/chrome-basic-auth.png)
## How does it Work? ## How does it Work?
Now that we know what basic authentication is, the question is, how does it work? The answer is: it is controlled by the response of the server. Now that we know what basic authentication is, the question is, how does it work? The answer is: it is controlled by the response of the server.
### Step 1 ### Step 1
When the browser first requests the server, the server tries to check the availability of the `Authorization` header in the request. Because it is the first request, no `Authorization` header is found in the request. So the server responds with the `401 Unauthorized` response code and also sends the `WWW-Authenticate` header with the value set to `Basic`, which tells the browser that it needs to trigger the basic authentication flow. When the browser first requests the server, the server tries to check the availability of the `Authorization` header in the request. Because it is the first request, no `Authorization` header is found in the request. So the server responds with the `401 Unauthorized` response code and also sends the `WWW-Authenticate` header with the value set to `Basic`, which tells the browser that it needs to trigger the basic authentication flow.
``` ```
@ -50,19 +52,23 @@ If you notice the response, we have an additional parameter called `realm`, whic
The browser might use Realm to cache the credential. In the future, when there is an authentication failure browser will check if it has the credentials in the cache for the given realm of the domain, and it may use the same credentials. The browser might use Realm to cache the credential. In the future, when there is an authentication failure browser will check if it has the credentials in the cache for the given realm of the domain, and it may use the same credentials.
## Step 2 ## Step 2
Upon receiving the response from the server, the browser will notice the `WWW-Authenticate` header and will show the authentication popup. Upon receiving the response from the server, the browser will notice the `WWW-Authenticate` header and will show the authentication popup.
![Chrome Basic Authentication](/guides/basic-authentication/chrome-basic-auth.png) ![Chrome Basic Authentication](/guides/basic-authentication/chrome-basic-auth.png)
## Step 3 ## Step 3
After the user submits the credentials through this authentication popup, the browser will automatically encode the credentials using the `base64` encoding and send them in the `Authorization` header of the same request. After the user submits the credentials through this authentication popup, the browser will automatically encode the credentials using the `base64` encoding and send them in the `Authorization` header of the same request.
### Step 4 ### Step 4
Upon receiving the request, the server will decode and verify the credentials. If the credentials are valid, the server will send the response to the client. Upon receiving the request, the server will decode and verify the credentials. If the credentials are valid, the server will send the response to the client.
So that is how Basic Authentication works. So that is how Basic Authentication works.
## Basic Authentication in Node.js ## Basic Authentication in Node.js
I have prepared the sample project in Node.js, which can be found on GitHub [kamranahmedse/node-basic-auth-example](https://github.com/kamranahmedse/node-basic-auth-example). If you look at the codebase of the project, we have two files `index.js` with the following content: I have prepared the sample project in Node.js, which can be found on GitHub [kamranahmedse/node-basic-auth-example](https://github.com/kamranahmedse/node-basic-auth-example). If you look at the codebase of the project, we have two files `index.js` with the following content:
```javascript ```javascript
@ -84,14 +90,14 @@ app.get('/', (req, res) => {
app.listen(port, () => { app.listen(port, () => {
console.log(`App running @ http://localhost:${port}`); console.log(`App running @ http://localhost:${port}`);
}) });
``` ```
As you can see, it's just a regular express server. `authMiddleware` registration is where we have all the code for "Basic Authentication". Here is the content of the middleware: As you can see, it's just a regular express server. `authMiddleware` registration is where we have all the code for "Basic Authentication". Here is the content of the middleware:
```javascript ```javascript
// src/auth.js // src/auth.js
const base64 = require("base-64"); const base64 = require('base-64');
function decodeCredentials(authHeader) { function decodeCredentials(authHeader) {
// ... // ...
@ -99,7 +105,9 @@ function decodeCredentials(authHeader) {
module.exports = function (req, res, next) { module.exports = function (req, res, next) {
// Take the header and decode credentials // Take the header and decode credentials
const [username, password] = decodeCredentials(req.headers.authorization || ''); const [username, password] = decodeCredentials(
req.headers.authorization || ''
);
// Verify the credentials // Verify the credentials
if (username === 'admin' && password === 'admin') { if (username === 'admin' && password === 'admin') {
@ -109,7 +117,7 @@ module.exports = function(req, res, next) {
// Respond with authenticate header on auth failure. // Respond with authenticate header on auth failure.
res.set('WWW-Authenticate', 'Basic realm="user_pages"'); res.set('WWW-Authenticate', 'Basic realm="user_pages"');
res.status(401).send('Authentication required.'); res.status(401).send('Authentication required.');
} };
``` ```
And that is how the basic authentication is implemented in Node.js. And that is how the basic authentication is implemented in Node.js.

@ -1,23 +1,23 @@
--- ---
title: "HTTP Caching" title: 'HTTP Caching'
description: "Everything you need to know about web caching" description: 'Everything you need to know about web caching'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "HTTP Caching - roadmap.sh" title: 'HTTP Caching - roadmap.sh'
description: "Everything you need to know about web caching" description: 'Everything you need to know about web caching'
isNew: false isNew: false
type: "textual" type: 'textual'
date: 2018-11-29 date: 2018-11-29
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
As users, we easily get frustrated by the buffering of videos, the images that take seconds to load, and pages that got stuck because the content is being loaded. Loading the resources from some cache is much faster than fetching the same from the originating server. It reduces latency, speeds up the loading of resources, decreases the load on the server, cuts down the bandwidth costs etc. As users, we easily get frustrated by the buffering of videos, the images that take seconds to load, and pages that got stuck because the content is being loaded. Loading the resources from some cache is much faster than fetching the same from the originating server. It reduces latency, speeds up the loading of resources, decreases the load on the server, cuts down the bandwidth costs etc.
@ -123,6 +123,7 @@ Cache-Control specifies how long and in what manner should the content be cached
Value for the `Cache-Control` header is composite i.e. it can have multiple directive/values. Let's look at the possible values that this header may contain. Value for the `Cache-Control` header is composite i.e. it can have multiple directive/values. Let's look at the possible values that this header may contain.
##### private ##### private
Setting the cache to `private` means that the content will not be cached in any of the proxies and it will only be cached by the client (i.e. browser) Setting the cache to `private` means that the content will not be cached in any of the proxies and it will only be cached by the client (i.e. browser)
```html ```html
@ -140,6 +141,7 @@ Cache-Control: public
``` ```
##### no-store ##### no-store
**`no-store`** specifies that the content is not to be cached by any of the caches **`no-store`** specifies that the content is not to be cached by any of the caches
```html ```html
@ -147,6 +149,7 @@ Cache-Control: no-store
``` ```
##### no-cache ##### no-cache
**`no-cache`** indicates that the cache can be maintained but the cached content is to be re-validated (using `ETag` for example) from the server before being served. That is, there is still a request to server but for validation and not to download the cached content. **`no-cache`** indicates that the cache can be maintained but the cached content is to be re-validated (using `ETag` for example) from the server before being served. That is, there is still a request to server but for validation and not to download the cached content.
```html ```html
@ -154,14 +157,17 @@ Cache-Control: max-age=3600, no-cache, public
``` ```
##### max-age: seconds ##### max-age: seconds
**`max-age`** specifies the number of seconds for which the content will be cached. For example, if the `cache-control` looks like below: **`max-age`** specifies the number of seconds for which the content will be cached. For example, if the `cache-control` looks like below:
```html ```html
Cache-Control: max-age=3600, public Cache-Control: max-age=3600, public
``` ```
it would mean that the content is publicly cacheable and will be considered stale after 60 minutes it would mean that the content is publicly cacheable and will be considered stale after 60 minutes
##### s-maxage: seconds ##### s-maxage: seconds
**`s-maxage`** here `s-` prefix stands for shared. This directive specifically targets the shared caches. Like `max-age` it also gets the number of seconds for which something is to be cached. If present, it will override `max-age` and `expires` headers for shared caching. **`s-maxage`** here `s-` prefix stands for shared. This directive specifically targets the shared caches. Like `max-age` it also gets the number of seconds for which something is to be cached. If present, it will override `max-age` and `expires` headers for shared caching.
```html ```html
@ -169,6 +175,7 @@ Cache-Control: s-maxage=3600, public
``` ```
##### must-revalidate ##### must-revalidate
**`must-revalidate`** it might happen sometimes that if you have network problems and the content cannot be retrieved from the server, the browser may serve stale content without validation. `must-revalidate` avoids that. If this directive is present, it means that stale content cannot be served in any case and the data must be re-validated from the server before serving. **`must-revalidate`** it might happen sometimes that if you have network problems and the content cannot be retrieved from the server, the browser may serve stale content without validation. `must-revalidate` avoids that. If this directive is present, it means that stale content cannot be served in any case and the data must be re-validated from the server before serving.
```html ```html
@ -176,18 +183,17 @@ Cache-Control: max-age=3600, public, must-revalidate
``` ```
##### proxy-revalidate ##### proxy-revalidate
**`proxy-revalidate`** is similar to `must-revalidate` but it specifies the same for shared or proxy caches. In other words `proxy-revalidate` is to `must-revalidate` as `s-maxage` is to `max-age`. But why did they not call it `s-revalidate`?. I have no idea why, if you have any clue please leave a comment below. **`proxy-revalidate`** is similar to `must-revalidate` but it specifies the same for shared or proxy caches. In other words `proxy-revalidate` is to `must-revalidate` as `s-maxage` is to `max-age`. But why did they not call it `s-revalidate`?. I have no idea why, if you have any clue please leave a comment below.
##### Mixing Values ##### Mixing Values
You can combine these directives in different ways to achieve different caching behaviors, however `no-cache/no-store` and `public/private` are mutually exclusive. You can combine these directives in different ways to achieve different caching behaviors, however `no-cache/no-store` and `public/private` are mutually exclusive.
If you specify both `no-store` and `no-cache`, `no-store` will be given precedence over `no-cache`. If you specify both `no-store` and `no-cache`, `no-store` will be given precedence over `no-cache`.
```html ```html
; If specified both ; If specified both Cache-Control: no-store, no-cache ; Below will be considered
Cache-Control: no-store, no-cache
; Below will be considered
Cache-Control: no-store Cache-Control: no-store
``` ```
@ -204,8 +210,8 @@ Etag or "entity tag" was introduced in HTTP/1.1 specs. Etag is just a unique ide
Method by which ETag is generated is not specified in the HTTP docs and usually some collision-resistant hash function is used to assign etags to each version of a resource. There could be two types of etags i.e. strong and weak Method by which ETag is generated is not specified in the HTTP docs and usually some collision-resistant hash function is used to assign etags to each version of a resource. There could be two types of etags i.e. strong and weak
```html ```html
ETag: "j82j8232ha7sdh0q2882" - Strong Etag ETag: "j82j8232ha7sdh0q2882" - Strong Etag ETag: W/"j82j8232ha7sdh0q2882" - Weak
ETag: W/"j82j8232ha7sdh0q2882" - Weak Etag (prefixed with `W/`) Etag (prefixed with `W/`)
``` ```
A strong validating ETag means that two resources are **exactly** same and there is no difference between them at all. While a weak ETag means that two resources although not strictly the same but could be considered the same. Weak etags might be useful for dynamic content, for example. A strong validating ETag means that two resources are **exactly** same and there is no difference between them at all. While a weak ETag means that two resources although not strictly the same but could be considered the same. Weak etags might be useful for dynamic content, for example.
@ -238,7 +244,7 @@ You might be questioning now, what if the cached content has both the `Last-Modi
### Where do I start? ### Where do I start?
Now that we have got *everything* covered, let us put everything in perspective and see how you can use this information. Now that we have got _everything_ covered, let us put everything in perspective and see how you can use this information.
#### Utilizing Server #### Utilizing Server
@ -247,8 +253,8 @@ Before we get into the possible caching strategies , let me add the fact that mo
**For example**, if you are using Apache and you have your static content placed at `/static`, you can put below `.htaccess` file in the directory to make all the content in it be cached for an year using below **For example**, if you are using Apache and you have your static content placed at `/static`, you can put below `.htaccess` file in the directory to make all the content in it be cached for an year using below
```html ```html
# Cache everything for an year # Cache everything for an year Header set Cache-Control "max-age=31536000,
Header set Cache-Control "max-age=31536000, public" public"
``` ```
You can further use `filesMatch` directive to add conditionals and use different caching strategy for different kinds of files e.g. You can further use `filesMatch` directive to add conditionals and use different caching strategy for different kinds of files e.g.

@ -1,23 +1,23 @@
--- ---
title: "Journey to HTTP/2" title: 'Journey to HTTP/2'
description: "The evolution of HTTP. How it all started and where we stand today" description: 'The evolution of HTTP. How it all started and where we stand today'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Journey to HTTP/2 - roadmap.sh" title: 'Journey to HTTP/2 - roadmap.sh'
description: "The evolution of HTTP. How it all started and where we stand today" description: 'The evolution of HTTP. How it all started and where we stand today'
isNew: false isNew: false
type: "textual" type: 'textual'
date: 2018-12-04 date: 2018-12-04
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
HTTP is the protocol that every web developer should know as it powers the whole web and knowing it is definitely going to help you develop better applications. In this guide, I am going to be discussing what HTTP is, how it came to be, where it is today and how did we get here. HTTP is the protocol that every web developer should know as it powers the whole web and knowing it is definitely going to help you develop better applications. In this guide, I am going to be discussing what HTTP is, how it came to be, where it is today and how did we get here.
@ -33,11 +33,11 @@ The first documented version of HTTP was [`HTTP/0.9`](https://www.w3.org/Protoco
```html ```html
GET /index.html GET /index.html
``` ```
And the response from server would have looked as follows And the response from server would have looked as follows
```html ```html
(response body) (response body) (connection closed)
(connection closed)
``` ```
That is, the server would get the request, reply with the HTML in response and as soon as the content has been transferred, the connection will be closed. There were That is, the server would get the request, reply with the HTML in response and as soon as the content has been transferred, the connection will be closed. There were
@ -57,10 +57,8 @@ Unlike `HTTP/0.9` which was only designed for HTML response, `HTTP/1.0` could no
Here is how a sample `HTTP/1.0` request and response might have looked like: Here is how a sample `HTTP/1.0` request and response might have looked like:
```html ```html
GET / HTTP/1.0 GET / HTTP/1.0 Host: kamranahmed.info User-Agent: Mozilla/5.0 (Macintosh; Intel
Host: kamranahmed.info Mac OS X 10_10_5) Accept: */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
``` ```
As you can see, alongside the request, client has also sent its personal information, required response type etc. While in `HTTP/0.9` client could never send such information because there were no headers. As you can see, alongside the request, client has also sent its personal information, required response type etc. While in `HTTP/0.9` client could never send such information because there were no headers.
@ -68,15 +66,9 @@ As you can see, alongside the request, client has also sent its personal informa
Example response to the request above may have looked like below Example response to the request above may have looked like below
```html ```html
HTTP/1.0 200 OK HTTP/1.0 200 OK Content-Type: text/plain Content-Length: 137582 Expires: Thu, 05
Content-Type: text/plain Dec 1997 16:00:00 GMT Last-Modified: Wed, 5 August 1996 15:55:28 GMT Server:
Content-Length: 137582 Apache 0.84 (response body) (connection closed)
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84
(response body)
(connection closed)
``` ```
In the very beginning of the response there is `HTTP/1.0` (HTTP followed by the version number), then there is the status code `200` followed by the reason phrase (or description of the status code, if you will). In the very beginning of the response there is `HTTP/1.0` (HTTP followed by the version number), then there is the status code `200` followed by the reason phrase (or description of the status code, if you will).
@ -164,7 +156,6 @@ By now, you must be convinced that why we needed another revision of the HTTP pr
![HTTP Model](https://i.imgur.com/S85j8gg.png) ![HTTP Model](https://i.imgur.com/S85j8gg.png)
#### 1. Binary Protocol #### 1. Binary Protocol
`HTTP/2` tends to address the issue of increased latency that existed in HTTP/1.x by making it a binary protocol. Being a binary protocol, it easier to parse but unlike `HTTP/1.x` it is no longer readable by the human eye. The major building blocks of `HTTP/2` are Frames and Streams `HTTP/2` tends to address the issue of increased latency that existed in HTTP/1.x by making it a binary protocol. Being a binary protocol, it easier to parse but unlike `HTTP/1.x` it is no longer readable by the human eye. The major building blocks of `HTTP/2` are Frames and Streams
@ -177,12 +168,10 @@ Every `HTTP/2` request and response is given a unique stream ID and it is divide
Apart from the `HEADERS` and `DATA`, another frame type that I think worth mentioning here is `RST_STREAM` which is a special frame type that is used to abort some stream i.e. client may send this frame to let the server know that I don't need this stream anymore. In `HTTP/1.1` the only way to make the server stop sending the response to client was closing the connection which resulted in increased latency because a new connection had to be opened for any consecutive requests. While in HTTP/2, client can use `RST_STREAM` and stop receiving a specific stream while the connection will still be open and the other streams will still be in play. Apart from the `HEADERS` and `DATA`, another frame type that I think worth mentioning here is `RST_STREAM` which is a special frame type that is used to abort some stream i.e. client may send this frame to let the server know that I don't need this stream anymore. In `HTTP/1.1` the only way to make the server stop sending the response to client was closing the connection which resulted in increased latency because a new connection had to be opened for any consecutive requests. While in HTTP/2, client can use `RST_STREAM` and stop receiving a specific stream while the connection will still be open and the other streams will still be in play.
#### 2. Multiplexing #### 2. Multiplexing
Since `HTTP/2` is now a binary protocol and as I said above that it uses frames and streams for requests and responses, once a TCP connection is opened, all the streams are sent asynchronously through the same connection without opening any additional connections. And in turn, the server responds in the same asynchronous way i.e. the response has no order and the client uses the assigned stream id to identify the stream to which a specific packet belongs. This also solves the **head-of-line blocking** issue that existed in HTTP/1.x i.e. the client will not have to wait for the request that is taking time and other requests will still be getting processed. Since `HTTP/2` is now a binary protocol and as I said above that it uses frames and streams for requests and responses, once a TCP connection is opened, all the streams are sent asynchronously through the same connection without opening any additional connections. And in turn, the server responds in the same asynchronous way i.e. the response has no order and the client uses the assigned stream id to identify the stream to which a specific packet belongs. This also solves the **head-of-line blocking** issue that existed in HTTP/1.x i.e. the client will not have to wait for the request that is taking time and other requests will still be getting processed.
#### 3. HPACK Header Compression #### 3. HPACK Header Compression
It was part of a separate RFC which was specifically aimed at optimizing the sent headers. The essence of it is that when we are constantly accessing the server from a same client there is alot of redundant data that we are sending in the headers over and over, and sometimes there might be cookies increasing the headers size which results in bandwidth usage and increased latency. To overcome this, `HTTP/2` introduced header compression. It was part of a separate RFC which was specifically aimed at optimizing the sent headers. The essence of it is that when we are constantly accessing the server from a same client there is alot of redundant data that we are sending in the headers over and over, and sometimes there might be cookies increasing the headers size which results in bandwidth usage and increased latency. To overcome this, `HTTP/2` introduced header compression.
@ -193,7 +182,6 @@ Unlike request and response, headers are not compressed in `gzip` or `compress`
While we are talking headers, let me add here that the headers are still the same as in HTTP/1.1, except for the addition of some pseudo headers i.e. `:method`, `:scheme`, `:host` and `:path` While we are talking headers, let me add here that the headers are still the same as in HTTP/1.1, except for the addition of some pseudo headers i.e. `:method`, `:scheme`, `:host` and `:path`
#### 4. Server Push #### 4. Server Push
Server push is another tremendous feature of `HTTP/2` where the server, knowing that the client is going to ask for a certain resource, can push it to the client without even client asking for it. For example, let's say a browser loads a web page, it parses the whole page to find out the remote content that it has to load from the server and then sends consequent requests to the server to get that content. Server push is another tremendous feature of `HTTP/2` where the server, knowing that the client is going to ask for a certain resource, can push it to the client without even client asking for it. For example, let's say a browser loads a web page, it parses the whole page to find out the remote content that it has to load from the server and then sends consequent requests to the server to get that content.

@ -1,24 +1,23 @@
--- ---
title: "JWT Authentication" title: 'JWT Authentication'
description: "Understand what is JWT authentication and how is it implemented" description: 'Understand what is JWT authentication and how is it implemented'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "JWT Authentication - roadmap.sh" title: 'JWT Authentication - roadmap.sh'
description: "Understand what is JWT authentication and how is it implemented" description: 'Understand what is JWT authentication and how is it implemented'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-06-20 date: 2021-06-20
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![JWT Authentication](/guides/jwt-authentication.png)](/guides/jwt-authentication.png) [![JWT Authentication](/guides/jwt-authentication.png)](/guides/jwt-authentication.png)

@ -1,23 +1,23 @@
--- ---
title: "Levels of Seniority" title: 'Levels of Seniority'
description: "How to Step Up as a Junior, Mid Level or a Senior Developer?" description: 'How to Step Up as a Junior, Mid Level or a Senior Developer?'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Levels of Seniority - roadmap.sh" title: 'Levels of Seniority - roadmap.sh'
description: "How to Step Up as a Junior, Mid Level or a Senior Developer?" description: 'How to Step Up as a Junior, Mid Level or a Senior Developer?'
isNew: false isNew: false
type: "textual" type: 'textual'
date: 2020-12-03 date: 2020-12-03
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
I have been working on redoing the [roadmaps](https://roadmap.sh) – splitting the skillset based on the seniority levels to make them easier to follow and not scare the new developers away. Since the roadmaps are going to be just about the technical knowledge, I thought it would be a good idea to reiterate and have an article on what I think of different seniority roles. I have been working on redoing the [roadmaps](https://roadmap.sh) – splitting the skillset based on the seniority levels to make them easier to follow and not scare the new developers away. Since the roadmaps are going to be just about the technical knowledge, I thought it would be a good idea to reiterate and have an article on what I think of different seniority roles.
@ -25,47 +25,50 @@ I have been working on redoing the [roadmaps](https://roadmap.sh) – splitting
I have seen many organizations decide the seniority of developers by giving more significance to the years of experience than they should. I have seen developers labeled "Junior" doing the work of Senior Developers and I have seen "Lead" developers who weren't even qualified to be called "Senior". The seniority of a developer cannot just be decided by their age, years of experience or technical knowledge that they have got. There are other factors in play here -- their perception of work, how they interact with their peers and how they approach problems. We discuss these three key factors in detail for each of the seniority levels below. I have seen many organizations decide the seniority of developers by giving more significance to the years of experience than they should. I have seen developers labeled "Junior" doing the work of Senior Developers and I have seen "Lead" developers who weren't even qualified to be called "Senior". The seniority of a developer cannot just be decided by their age, years of experience or technical knowledge that they have got. There are other factors in play here -- their perception of work, how they interact with their peers and how they approach problems. We discuss these three key factors in detail for each of the seniority levels below.
### Different Seniority Titles ### Different Seniority Titles
Different organizations might have different seniority titles but they mainly fall into three categories: Different organizations might have different seniority titles but they mainly fall into three categories:
* Junior Developer - Junior Developer
* Mid Level Developer - Mid Level Developer
* Senior Developer - Senior Developer
### Junior Developer ### Junior Developer
Junior developers are normally fresh graduates and it's either they don't have or they have minimal industry experience. Not only they have weak coding skills but there are also a few other things that give Junior developers away: Junior developers are normally fresh graduates and it's either they don't have or they have minimal industry experience. Not only they have weak coding skills but there are also a few other things that give Junior developers away:
* Their main mantra is "making it work" without giving much attention to how the solution is achieved. To them, a working software and good software are equivalent. - Their main mantra is "making it work" without giving much attention to how the solution is achieved. To them, a working software and good software are equivalent.
* They usually require very specific and structured directions to achieve something. They suffer from tunnel vision, need supervision and continuous guidance to be effective team members. - They usually require very specific and structured directions to achieve something. They suffer from tunnel vision, need supervision and continuous guidance to be effective team members.
* Most of the Junior developers just try to live up to the role and, when stuck, they might leave work for a senior developer instead of at least trying to take a stab at something. - Most of the Junior developers just try to live up to the role and, when stuck, they might leave work for a senior developer instead of at least trying to take a stab at something.
* They don't know about the business side of the company and don't realize how management/sales/marketing/etc think and they don't realize how much rework, wasted effort, and end-user aggravation could be saved by getting to know the business domain. - They don't know about the business side of the company and don't realize how management/sales/marketing/etc think and they don't realize how much rework, wasted effort, and end-user aggravation could be saved by getting to know the business domain.
* Over-engineering is a major problem, often leading to fragility and bugs. - Over-engineering is a major problem, often leading to fragility and bugs.
* When given a problem, they often try to fix just the current problem a.k.a. fixing the symptoms instead of fixing the root problem. - When given a problem, they often try to fix just the current problem a.k.a. fixing the symptoms instead of fixing the root problem.
* You might notice the "[Somebody Else's Problem](https://en.wikipedia.org/wiki/Somebody_else%27s_problem)" behavior from them. - You might notice the "[Somebody Else's Problem](https://en.wikipedia.org/wiki/Somebody_else%27s_problem)" behavior from them.
* They don't know what or how much they don't know, thanks to the [Dunning–Kruger effect](https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect). - They don't know what or how much they don't know, thanks to the [Dunning–Kruger effect](https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect).
* They don't take initiatives and they might be afraid to work on an unfamiliar codebase. - They don't take initiatives and they might be afraid to work on an unfamiliar codebase.
* They don't participate in team discussions. - They don't participate in team discussions.
Being a Junior developer in the team is not necessarily a bad thing; since you are just starting out, you are not expected to be a know-it-all person. However, it is your responsibility to learn, gain experience, not get stuck with the "Junior" title and improve yourself. Here are a few tips for Junior developers to help move up the ladder of seniority: Being a Junior developer in the team is not necessarily a bad thing; since you are just starting out, you are not expected to be a know-it-all person. However, it is your responsibility to learn, gain experience, not get stuck with the "Junior" title and improve yourself. Here are a few tips for Junior developers to help move up the ladder of seniority:
* All sorts of problems can be solved if you work on them long enough. Do not give up if Stack Overflow or an issue on GitHub doesn't have an answer. Saying "I am stuck, but I have tried X, Y, and Z. Do you have any pointers?" to your lead is much better than saying "This is beyond me." - All sorts of problems can be solved if you work on them long enough. Do not give up if Stack Overflow or an issue on GitHub doesn't have an answer. Saying "I am stuck, but I have tried X, Y, and Z. Do you have any pointers?" to your lead is much better than saying "This is beyond me."
* Read a lot of code, not just code in the projects that you are working on, but reference/framework source code, open-source. Ask your fellow developers, perhaps on Reddit too, about the good open-source examples for the language/tools of your choice. - Read a lot of code, not just code in the projects that you are working on, but reference/framework source code, open-source. Ask your fellow developers, perhaps on Reddit too, about the good open-source examples for the language/tools of your choice.
* Do personal side-projects, share them with people, contribute to the open-source community. Reach out to people for help. You will be surprised how much support you can get from the community. I still remember my first open-source project on GitHub from around 6 years ago which was a small PHP script (a library) that fetched details for a given address from Google's Geocoding API. The codebase was super messy, it did not have any tests, did not have any linters or sniffers, and it did not have any CI because I didn't know about any of this at that time. I am not sure how but one kind soul somehow found the project, forked it, refactored it, "modernized" it, added linting, code sniffing, added CI and opened the pull request. This one pull request taught me so many things that I might have never learned that fast on my own because I was still in college, working for a small service-based company and doing just small websites all on my own without knowing what is right and what is not. This one PR on GitHub was my introduction to open-source and I owe everything to that. - Do personal side-projects, share them with people, contribute to the open-source community. Reach out to people for help. You will be surprised how much support you can get from the community. I still remember my first open-source project on GitHub from around 6 years ago which was a small PHP script (a library) that fetched details for a given address from Google's Geocoding API. The codebase was super messy, it did not have any tests, did not have any linters or sniffers, and it did not have any CI because I didn't know about any of this at that time. I am not sure how but one kind soul somehow found the project, forked it, refactored it, "modernized" it, added linting, code sniffing, added CI and opened the pull request. This one pull request taught me so many things that I might have never learned that fast on my own because I was still in college, working for a small service-based company and doing just small websites all on my own without knowing what is right and what is not. This one PR on GitHub was my introduction to open-source and I owe everything to that.
* Avoid what is known as ["Somebody Else's Problem Field"](https://en.wikipedia.org/wiki/Somebody_else%27s_problem) behavior. - Avoid what is known as ["Somebody Else's Problem Field"](https://en.wikipedia.org/wiki/Somebody_else%27s_problem) behavior.
* When given a problem to solve, try to identify the root cause and fix that instead of fixing the symptoms. And remember, not being able to reproduce means not solved. It is solved when you understand why it occurred and why it no longer does. - When given a problem to solve, try to identify the root cause and fix that instead of fixing the symptoms. And remember, not being able to reproduce means not solved. It is solved when you understand why it occurred and why it no longer does.
* Have respect for the code that was written before you. Be generous when passing judgment on the architecture or the design decisions made in the codebase. Understand that code is often ugly and weird for a reason other than incompetence. Learning to live with and thrive with legacy code is a great skill. Never assume anybody is stupid. Instead, figure out how these intelligent, well-intentioned and experienced people have come to a decision that is stupid now. Approach inheriting legacy code with an "opportunity mindset" rather than a complaining one. - Have respect for the code that was written before you. Be generous when passing judgment on the architecture or the design decisions made in the codebase. Understand that code is often ugly and weird for a reason other than incompetence. Learning to live with and thrive with legacy code is a great skill. Never assume anybody is stupid. Instead, figure out how these intelligent, well-intentioned and experienced people have come to a decision that is stupid now. Approach inheriting legacy code with an "opportunity mindset" rather than a complaining one.
* It's okay to not know things. You don't need to be ashamed of not knowing things already. There are no stupid questions, ask however many questions that would allow you to work effectively. - It's okay to not know things. You don't need to be ashamed of not knowing things already. There are no stupid questions, ask however many questions that would allow you to work effectively.
* Don't let yourself be limited by the job title that you have. Keep working on your self-improvement. - Don't let yourself be limited by the job title that you have. Keep working on your self-improvement.
* Do your homework. Predict what’s coming down the pipe. Be involved in the team discussions. Even if you are wrong, you will learn something. - Do your homework. Predict what’s coming down the pipe. Be involved in the team discussions. Even if you are wrong, you will learn something.
* Learn about the domain that you are working with. Understand the product end-to-end as an end-user. Do not assume things, ask questions and get things cleared when in doubt. - Learn about the domain that you are working with. Understand the product end-to-end as an end-user. Do not assume things, ask questions and get things cleared when in doubt.
* Learn to communicate effectively - soft skills matter. Learn how to write good emails, how to present your work, how to phrase your questions in a thoughtful manner. - Learn to communicate effectively - soft skills matter. Learn how to write good emails, how to present your work, how to phrase your questions in a thoughtful manner.
* Sit with the senior developers, watch them work, find a mentor. No one likes a know-it-all. Get hold of your ego and be humble enough to take lessons from experienced people. - Sit with the senior developers, watch them work, find a mentor. No one likes a know-it-all. Get hold of your ego and be humble enough to take lessons from experienced people.
* Don't just blindly follow the advice of "experts", take it with a grain of salt. - Don't just blindly follow the advice of "experts", take it with a grain of salt.
* If you are asked to provide an estimate for some work, do not give an answer unless you have all the details to make a reasonable estimate. If you are forced to do that, pad it 2x or more depending on how much you don't know about what needs to be done for the task to be marked 'done'. - If you are asked to provide an estimate for some work, do not give an answer unless you have all the details to make a reasonable estimate. If you are forced to do that, pad it 2x or more depending on how much you don't know about what needs to be done for the task to be marked 'done'.
* Take some time to learn how to use a debugger. Debuggers are quite beneficial when navigating new, undocumented or poorly documented codebase, or to debug weird issues. - Take some time to learn how to use a debugger. Debuggers are quite beneficial when navigating new, undocumented or poorly documented codebase, or to debug weird issues.
* Avoid saying "it works on my machine" -- yes, I have heard that a lot. - Avoid saying "it works on my machine" -- yes, I have heard that a lot.
* Try to turn any feelings of inadequacy or imposter syndrome into energy to push yourself forward and increase your skills and knowledge. - Try to turn any feelings of inadequacy or imposter syndrome into energy to push yourself forward and increase your skills and knowledge.
### Mid Level Developers ### Mid Level Developers
The next level after the Junior developers is Mid Level developers. They are technically stronger than the Junior developers and can work with minimal supervision. They still have some issues to address in order to jump to Senior level. The next level after the Junior developers is Mid Level developers. They are technically stronger than the Junior developers and can work with minimal supervision. They still have some issues to address in order to jump to Senior level.
Intermediate developers are more competent than the Junior developer. They start to see the flaws in their old codebase. They gain the knowledge but they get trapped into the next chain i.e. messing things up while trying to do them "the right way" e.g. hasty abstractions, overuse or unnecessary usage of Design Patterns -- they may be able to provide solution faster than the Junior developers but the solution might put you into another rabbit-hole in the long run. Without supervision, they might delay the execution while trying to "do things properly". They don't know when to make tradeoffs and they still don't know when to be dogmatic and when to be pragmatic. They can easily become attached to their solution, become myopic, and be unable to take feedback. Intermediate developers are more competent than the Junior developer. They start to see the flaws in their old codebase. They gain the knowledge but they get trapped into the next chain i.e. messing things up while trying to do them "the right way" e.g. hasty abstractions, overuse or unnecessary usage of Design Patterns -- they may be able to provide solution faster than the Junior developers but the solution might put you into another rabbit-hole in the long run. Without supervision, they might delay the execution while trying to "do things properly". They don't know when to make tradeoffs and they still don't know when to be dogmatic and when to be pragmatic. They can easily become attached to their solution, become myopic, and be unable to take feedback.
@ -73,20 +76,22 @@ Intermediate developers are more competent than the Junior developer. They start
Mid-level developers are quite common. Most of the organizations wrongly label them as "Senior Developers". However, they need further mentoring in order to become Senior Developers. The next section describes the responsibilities of a senior developer and how you can become one. Mid-level developers are quite common. Most of the organizations wrongly label them as "Senior Developers". However, they need further mentoring in order to become Senior Developers. The next section describes the responsibilities of a senior developer and how you can become one.
### Senior Developers ### Senior Developers
Senior developers are the next level after the Mid-level developers. They are the people who can get things done on their own without any supervision and without creating any issues down the road. They are more mature, have gained experience by delivering both good and bad software in the past and have learned from it — they know how to be pragmatic. Here is the list of things that are normally expected of a Senior Developer: Senior developers are the next level after the Mid-level developers. They are the people who can get things done on their own without any supervision and without creating any issues down the road. They are more mature, have gained experience by delivering both good and bad software in the past and have learned from it — they know how to be pragmatic. Here is the list of things that are normally expected of a Senior Developer:
* With their past experiences, mistakes made, issues faced by over-designed or under-designed software, they can foresee the problems and persuade the direction of the codebase or the architecture. - With their past experiences, mistakes made, issues faced by over-designed or under-designed software, they can foresee the problems and persuade the direction of the codebase or the architecture.
* They don't have a "Shiny-Toy" syndrome. They are pragmatic in the execution. They can make the tradeoffs when required, and they know why. They know where to be dogmatic and where to be pragmatic. - They don't have a "Shiny-Toy" syndrome. They are pragmatic in the execution. They can make the tradeoffs when required, and they know why. They know where to be dogmatic and where to be pragmatic.
* They have a good picture of the field, know what the best tool for the job is in most cases (even if they don't know the tool). They have the innate ability to pick up a new tool/language/paradigm/etc in order to solve a problem that requires it. - They have a good picture of the field, know what the best tool for the job is in most cases (even if they don't know the tool). They have the innate ability to pick up a new tool/language/paradigm/etc in order to solve a problem that requires it.
* They are aware they're on a team. They view it as a part of their responsibility to mentor others. This can range from pair programming with junior devs to taking un-glorious tasks of writing docs or tests or whatever else needs to be done. - They are aware they're on a team. They view it as a part of their responsibility to mentor others. This can range from pair programming with junior devs to taking un-glorious tasks of writing docs or tests or whatever else needs to be done.
* They have a deep understanding of the domain - they know about the business side of the company and realize how management/sales/marketing/etc think and benefit from their knowledge of the business domain during the development. - They have a deep understanding of the domain - they know about the business side of the company and realize how management/sales/marketing/etc think and benefit from their knowledge of the business domain during the development.
* They don't make empty complaints, they make judgments based on the empirical evidence and they have suggestions for solutions. - They don't make empty complaints, they make judgments based on the empirical evidence and they have suggestions for solutions.
* They think much more than just code - they know that their job is to provide solutions to the problems and not just to write code. - They think much more than just code - they know that their job is to provide solutions to the problems and not just to write code.
* They have the ability to take on large ill-defined problems, define them, break them up, and execute the pieces. A senior developer can take something big and abstract, and run with it. They will come up with a few options, discuss them with the team and implement them. - They have the ability to take on large ill-defined problems, define them, break them up, and execute the pieces. A senior developer can take something big and abstract, and run with it. They will come up with a few options, discuss them with the team and implement them.
* They have respect for the code that was written before them. They are generous when passing judgment on the architecture or the design decisions made in the codebase. They approach inheriting legacy code with an "opportunity mindset" rather than a complaining one. - They have respect for the code that was written before them. They are generous when passing judgment on the architecture or the design decisions made in the codebase. They approach inheriting legacy code with an "opportunity mindset" rather than a complaining one.
* They know how to give feedback without hurting anyone. - They know how to give feedback without hurting anyone.
### Conclusion ### Conclusion
All teams are made up of a mix of all these seniority roles. Being content with your role is a bad thing and you should always strive to improve yourself for the next step. This article is based on my beliefs and observations in the industry. Lots of companies care more for the years of experience to decide the seniority which is a crappy metric -- you don't gain experience just by spending years. You gain it by continuously solving different sorts of problems, irrespective of the number of years you spend in the industry. I have seen fresh graduates having no industry experience get up to speed quickly and producing work of a Senior Engineer and I have seen Senior developers labeled "senior" merely because of their age and "years of experience". All teams are made up of a mix of all these seniority roles. Being content with your role is a bad thing and you should always strive to improve yourself for the next step. This article is based on my beliefs and observations in the industry. Lots of companies care more for the years of experience to decide the seniority which is a crappy metric -- you don't gain experience just by spending years. You gain it by continuously solving different sorts of problems, irrespective of the number of years you spend in the industry. I have seen fresh graduates having no industry experience get up to speed quickly and producing work of a Senior Engineer and I have seen Senior developers labeled "senior" merely because of their age and "years of experience".
The most important traits that you need to have in order to step up in your career are: not settling with mediocrity, having an open mindset, being humble, learning from your mistakes, working on the challenging problems and having an opportunity mindset rather than a complaining one. The most important traits that you need to have in order to step up in your career are: not settling with mediocrity, having an open mindset, being humble, learning from your mistakes, working on the challenging problems and having an opportunity mindset rather than a complaining one.

@ -1,24 +1,23 @@
--- ---
title: "OAuth — Open Authorization" title: 'OAuth — Open Authorization'
description: "Learn and understand what is OAuth and how it works" description: 'Learn and understand what is OAuth and how it works'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "OAuth — Open Authorization - roadmap.sh" title: 'OAuth — Open Authorization - roadmap.sh'
description: "Learn and understand what is OAuth and how it works" description: 'Learn and understand what is OAuth and how it works'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-06-28 date: 2021-06-28
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![OAuth - Open Authorization](/guides/oauth.png)](/guides/oauth.png) [![OAuth - Open Authorization](/guides/oauth.png)](/guides/oauth.png)

@ -1,23 +1,23 @@
--- ---
title: "Proxy Servers" title: 'Proxy Servers'
description: "How do proxy servers work and what are forward and reverse proxies?" description: 'How do proxy servers work and what are forward and reverse proxies?'
author: author:
name: "Ebrahim Bharmal" name: 'Ebrahim Bharmal'
url: "https://twitter.com/BharmalEbrahim" url: 'https://twitter.com/BharmalEbrahim'
imageUrl: "/authors/ebrahimbharmal007.png" imageUrl: '/authors/ebrahimbharmal007.png'
seo: seo:
title: "Proxy Servers - roadmap.sh" title: 'Proxy Servers - roadmap.sh'
description: "How do proxy servers work and what are forward and reverse proxies?" description: 'How do proxy servers work and what are forward and reverse proxies?'
isNew: false isNew: false
type: "textual" type: 'textual'
date: 2017-10-24 date: 2017-10-24
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
The Internet has connected people across the world using social media and audio/video calling features along with providing an overabundance of knowledge and tools. All this comes with an inherent danger of security and privacy breaches. In this guide, we will talk about **proxies** that play a vital role in mitigating these risks. We will cover the following topics in this guide: The Internet has connected people across the world using social media and audio/video calling features along with providing an overabundance of knowledge and tools. All this comes with an inherent danger of security and privacy breaches. In this guide, we will talk about **proxies** that play a vital role in mitigating these risks. We will cover the following topics in this guide:
@ -29,9 +29,10 @@ The Internet has connected people across the world using social media and audio/
## Proxy Server ## Proxy Server
***Every web request which is sent from the client to a web server goes through some type of proxy server.*** A proxy server acts as a gateway between client *(you)* and the internet and separates end-users from the websites you browse. It replaces the source IP address of the web request with the proxy server's IP address and then forwards it to the web server. The web server is unaware of the client, it only sees the proxy server. **_Every web request which is sent from the client to a web server goes through some type of proxy server._** A proxy server acts as a gateway between client _(you)_ and the internet and separates end-users from the websites you browse. It replaces the source IP address of the web request with the proxy server's IP address and then forwards it to the web server. The web server is unaware of the client, it only sees the proxy server.
![Proxy Server Description](/guides/proxy/proxy-example.png) ![Proxy Server Description](/guides/proxy/proxy-example.png)
> NOTE: This is not an accurate description but rather just an illustration. > NOTE: This is not an accurate description but rather just an illustration.
Proxy servers serve as a single point of control making it easier to enforce security policies. It also provides caching mechanism which stores the requested web pages on the proxy server to improve performance. If the requested web-page is available in cache memory then instead of forwarding the request to the web-server it will send the cached webpage back to the client. This **saves big companies thousands of dollars** by reducing the load on their servers as their website is visited by millions of users every day. Proxy servers serve as a single point of control making it easier to enforce security policies. It also provides caching mechanism which stores the requested web pages on the proxy server to improve performance. If the requested web-page is available in cache memory then instead of forwarding the request to the web-server it will send the cached webpage back to the client. This **saves big companies thousands of dollars** by reducing the load on their servers as their website is visited by millions of users every day.
@ -41,6 +42,7 @@ Proxy servers serve as a single point of control making it easier to enforce sec
A forward proxy is generally implemented on the client side and **sits in front of multiple clients** or client sources. Forward proxy servers are mainly used by companies to **manage the internet usage** of their employees and **restrict content**. It is also used as a **firewall** to secure the company's network by blocking any request which would pose threat to the company's network. Proxy servers are also used to **bypass geo-restriction** and browse content that might be blocked in the user's country. It enables users to **browse anonymously**, as the proxy server masks their details from the website's servers. A forward proxy is generally implemented on the client side and **sits in front of multiple clients** or client sources. Forward proxy servers are mainly used by companies to **manage the internet usage** of their employees and **restrict content**. It is also used as a **firewall** to secure the company's network by blocking any request which would pose threat to the company's network. Proxy servers are also used to **bypass geo-restriction** and browse content that might be blocked in the user's country. It enables users to **browse anonymously**, as the proxy server masks their details from the website's servers.
![Forward Proxy Description](/guides/proxy/forward-proxy.png) ![Forward Proxy Description](/guides/proxy/forward-proxy.png)
> NOTE: This is not an accurate description but rather just an illustration > NOTE: This is not an accurate description but rather just an illustration
## Reverse Proxy Server ## Reverse Proxy Server
@ -48,11 +50,12 @@ A forward proxy is generally implemented on the client side and **sits in front
Reverse proxy servers are implemented on the **server side** instead of the client side. It **sits in front of multiple webservers** and manages incoming requests by forwarding them to the web servers. It provides anonymity for the **back-end web servers and not the client**. Reverse proxy servers are generally used to perform tasks such as **authentication, content caching, and encryption/decryption** on behalf of the web server. These tasks would **hog CPU cycles** on the web server and degrade the performance of the website by introducing a high amount of delay in loading the webpage. Reverse proxies are also used as **load balancers** to distribute the incoming traffic efficiently among the web servers but it is **not optimized** for this task. In essence, a reverse proxy server is a gateway to a web-server or group of web-servers. Reverse proxy servers are implemented on the **server side** instead of the client side. It **sits in front of multiple webservers** and manages incoming requests by forwarding them to the web servers. It provides anonymity for the **back-end web servers and not the client**. Reverse proxy servers are generally used to perform tasks such as **authentication, content caching, and encryption/decryption** on behalf of the web server. These tasks would **hog CPU cycles** on the web server and degrade the performance of the website by introducing a high amount of delay in loading the webpage. Reverse proxies are also used as **load balancers** to distribute the incoming traffic efficiently among the web servers but it is **not optimized** for this task. In essence, a reverse proxy server is a gateway to a web-server or group of web-servers.
![Reverse Proxy Description](/guides/proxy/reverse-proxy.png) ![Reverse Proxy Description](/guides/proxy/reverse-proxy.png)
> NOTE: This is not an accurate description but rather just an illustration. Red lines represent the server's response and black lines represent the initial request from client(s). > NOTE: This is not an accurate description but rather just an illustration. Red lines represent the server's response and black lines represent the initial request from client(s).
## Summary ## Summary
A proxy server acts as a gateway between client *(you)* and the internet and separates end-users from the websites you browse. ***The position of the proxy server on the network determines whether it is a forward or a reverse proxy server***. A Forward proxy is implemented on the client side and **sits in front of multiple clients** or client sources and forwards requests to the web server. Reverse proxy servers are implemented on the **server side** it **sits in front of multiple webservers** and manage the incoming requests by forwarding them to the web servers. A proxy server acts as a gateway between client _(you)_ and the internet and separates end-users from the websites you browse. **_The position of the proxy server on the network determines whether it is a forward or a reverse proxy server_**. A Forward proxy is implemented on the client side and **sits in front of multiple clients** or client sources and forwards requests to the web server. Reverse proxy servers are implemented on the **server side** it **sits in front of multiple webservers** and manage the incoming requests by forwarding them to the web servers.
If all this was too much to take in, I have a simple analogy for you. If all this was too much to take in, I have a simple analogy for you.
@ -60,10 +63,10 @@ At a restaurant, the waiter/waitress takes your order and gives it to the kitche
In this analogy: In this analogy:
* You are the client - You are the client
* Your order is the web request - Your order is the web request
* Waiter/Waitress is your forward proxy server - Waiter/Waitress is your forward proxy server
* Kitchen head chef is the reverse proxy server - Kitchen head chef is the reverse proxy server
* Other chefs working in the kitchen are the web servers - Other chefs working in the kitchen are the web servers
With that said our guide comes to an end. Thank you for reading and feel free to submit any updates to the guide using the links below. With that said our guide comes to an end. Thank you for reading and feel free to submit any updates to the guide using the links below.

@ -1,26 +1,25 @@
--- ---
title: "Random Numbers: Are they?" title: 'Random Numbers: Are they?'
description: "Learn how they are generated and why they may not be truly random." description: 'Learn how they are generated and why they may not be truly random.'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Random Numbers: Are they? - roadmap.sh" title: 'Random Numbers: Are they? - roadmap.sh'
description: "Learn how they are generated and why they may not be truly random." description: 'Learn how they are generated and why they may not be truly random.'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-03-14 date: 2021-03-14
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
Random numbers are everywhere from computer games to lottery systems, graphics software, statistical sampling, computer simulation and cryptography. Graphic below is a quick explanation to how the random numbers are generated and why they may not be truly random. Random numbers are everywhere from computer games to lottery systems, graphics software, statistical sampling, computer simulation and cryptography. Graphic below is a quick explanation to how the random numbers are generated and why they may not be truly random.
[![Random Numbers](/guides/random-numbers.png)](/guides/random-numbers.png) [![Random Numbers](/guides/random-numbers.png)](/guides/random-numbers.png)

@ -1,26 +1,25 @@
--- ---
title: "Scaling Databases" title: 'Scaling Databases'
description: "Learn the ups and downs of different database scaling strategies" description: 'Learn the ups and downs of different database scaling strategies'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Scaling Databases - roadmap.sh" title: 'Scaling Databases - roadmap.sh'
description: "Learn the ups and downs of different database scaling strategies" description: 'Learn the ups and downs of different database scaling strategies'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-02-18 date: 2021-02-18
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
The chart below aims to give you a really basic understanding of how the capability of a DBMS is increased to handle a growing amount of load. The chart below aims to give you a really basic understanding of how the capability of a DBMS is increased to handle a growing amount of load.
[![Scaling Databases](/guides/scaling-databases.svg)](/guides/scaling-databases.svg) [![Scaling Databases](/guides/scaling-databases.svg)](/guides/scaling-databases.svg)

@ -1,24 +1,23 @@
--- ---
title: "Session Based Authentication" title: 'Session Based Authentication'
description: "Understand what is session based authentication and how it is implemented" description: 'Understand what is session based authentication and how it is implemented'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Session Based Authentication - roadmap.sh" title: 'Session Based Authentication - roadmap.sh'
description: "Understand what is session based authentication and how it is implemented" description: 'Understand what is session based authentication and how it is implemented'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-05-26 date: 2021-05-26
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![Session Authentication](/guides/session-authentication.png)](/guides/session-authentication.png) [![Session Authentication](/guides/session-authentication.png)](/guides/session-authentication.png)

@ -1,43 +1,46 @@
--- ---
title: "Session Based Authentication" title: 'Session Based Authentication'
description: "Learn what is Session Based Authentication and how to implement it in Node.js" description: 'Learn what is Session Based Authentication and how to implement it in Node.js'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Session Based Authentication - roadmap.sh" title: 'Session Based Authentication - roadmap.sh'
description: "Learn what is Session Based Authentication and how to implement it in Node.js" description: 'Learn what is Session Based Authentication and how to implement it in Node.js'
isNew: false isNew: false
type: "textual" type: 'textual'
date: 2022-11-01 date: 2022-11-01
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
HTTP is the internet protocol that standardizes how clients and servers interact with each other. When you open a website, among other things, HTTP is the protocol that helps load the website in the browser. HTTP is the internet protocol that standardizes how clients and servers interact with each other. When you open a website, among other things, HTTP is the protocol that helps load the website in the browser.
## HTTP is Stateless ## HTTP is Stateless
HTTP is a stateless protocol which means that each request made from the client to the server is treated as a standalone request; neither the client nor the server keeps track of the subsequent requests. Sessions allow you to change that; with sessions, the server has a way to associate some information with the client so that when the same client requests the server, it can retrieve that information. HTTP is a stateless protocol which means that each request made from the client to the server is treated as a standalone request; neither the client nor the server keeps track of the subsequent requests. Sessions allow you to change that; with sessions, the server has a way to associate some information with the client so that when the same client requests the server, it can retrieve that information.
In this guide, we will learn what is Session-Based Authentication and how to implement it in Node.js. We also have a separate [visual guide on Session-Based Authentication](/guides/session-authentication) as well that explains the topic visually. In this guide, we will learn what is Session-Based Authentication and how to implement it in Node.js. We also have a separate [visual guide on Session-Based Authentication](/guides/session-authentication) as well that explains the topic visually.
## What is Session-Based Authentication? ## What is Session-Based Authentication?
Session-based authentication is a stateful authentication technique where we use sessions to keep track of the authenticated user. Here is how Session Based Authentication works: Session-based authentication is a stateful authentication technique where we use sessions to keep track of the authenticated user. Here is how Session Based Authentication works:
* User submits the login request for authentication. - User submits the login request for authentication.
* Server validates the credentials. If the credentials are valid, the server initiates a session and stores some information about the client. This information can be stored in memory, file system, or database. The server also generates a unique identifier that it can later use to retrieve this session information from the storage. Server sends this unique session identifier to the client. - Server validates the credentials. If the credentials are valid, the server initiates a session and stores some information about the client. This information can be stored in memory, file system, or database. The server also generates a unique identifier that it can later use to retrieve this session information from the storage. Server sends this unique session identifier to the client.
* Client saves the session id in a cookie and this cookie is sent to the server in each request made after the authentication. - Client saves the session id in a cookie and this cookie is sent to the server in each request made after the authentication.
* Server, upon receiving a request, checks if the session id is present in the request and uses this session id to get information about the client. - Server, upon receiving a request, checks if the session id is present in the request and uses this session id to get information about the client.
And that is how session-based authentication works. And that is how session-based authentication works.
## Session-Based Authentication in Node.js ## Session-Based Authentication in Node.js
Now that we know what session-based authentication is, let's see how we can implement session-based authentication in Node.js. Now that we know what session-based authentication is, let's see how we can implement session-based authentication in Node.js.
Please note that, for the sake of simplicity, I have intentionally kept the project strictly relevant to the Session Based Authentication and have left out a lot of details that a production-ready application may require. Also, if you don't want to follow along, project [codebase can be found on GitHub](https://github.com/kamranahmedse/node-session-auth-example). Please note that, for the sake of simplicity, I have intentionally kept the project strictly relevant to the Session Based Authentication and have left out a lot of details that a production-ready application may require. Also, if you don't want to follow along, project [codebase can be found on GitHub](https://github.com/kamranahmedse/node-session-auth-example).
@ -47,17 +50,23 @@ First things first, create an empty directory that will be holding our applicati
```shell ```shell
mkdir session-auth-example mkdir session-auth-example
``` ```
Now run the following command to setup a sample `package.json` file: Now run the following command to setup a sample `package.json` file:
```shell ```shell
npm init -y npm init -y
``` ```
Next, we need to install the dependencies: Next, we need to install the dependencies:
```shell ```shell
npm install express express-session npm install express express-session
``` ```
`Express` is the application framework, and `express-session` is the package that helps work with sessions easily. `Express` is the application framework, and `express-session` is the package that helps work with sessions easily.
### Setting up the server ### Setting up the server
Now create an `index.js` file at the root of the project with the following content: Now create an `index.js` file at the root of the project with the following content:
```javascript ```javascript
@ -66,14 +75,16 @@ const sessions = require('express-session');
const app = express(); const app = express();
app.use(sessions({ app.use(
secret: "some secret", sessions({
secret: 'some secret',
cookie: { cookie: {
maxAge: 1000 * 60 * 60 * 24 // 24 hours maxAge: 1000 * 60 * 60 * 24, // 24 hours
}, },
resave: true, resave: true,
saveUninitialized: false, saveUninitialized: false,
})); })
);
app.use(express.json()); app.use(express.json());
app.use(express.urlencoded({ extended: true })); app.use(express.urlencoded({ extended: true }));
@ -84,17 +95,20 @@ app.listen(3000, () => {
console.log(`Server Running at port 3000`); console.log(`Server Running at port 3000`);
}); });
``` ```
The important piece to note here is the `express-session` middleware registration which automatically handles the session initialization, cooking parsing and session data retrieval, and so on. In our example here, we are passing the following configuration options: The important piece to note here is the `express-session` middleware registration which automatically handles the session initialization, cooking parsing and session data retrieval, and so on. In our example here, we are passing the following configuration options:
* `secret`: This is used to sign the session ID cookie. Using a secret that cannot be guessed will reduce the ability to hijack a session.
* `cookie`: Object containing the configuration for session id cookie. - `secret`: This is used to sign the session ID cookie. Using a secret that cannot be guessed will reduce the ability to hijack a session.
* `resave`: Forces the session to be saved back to the session store, even if the session data was never modified during the request. - `cookie`: Object containing the configuration for session id cookie.
* `saveUninitialized`: Forces an "uninitialized" session to be saved to the store, i.e., saves a session to the store even if the session was not initiated. - `resave`: Forces the session to be saved back to the session store, even if the session data was never modified during the request.
- `saveUninitialized`: Forces an "uninitialized" session to be saved to the store, i.e., saves a session to the store even if the session was not initiated.
Another important option is `store` which we can configure to change how/where the session data is stored on the server. By default, this data is stored in the memory, i.e., `MemoryStore`. Another important option is `store` which we can configure to change how/where the session data is stored on the server. By default, this data is stored in the memory, i.e., `MemoryStore`.
Look at the [express-session documentation](https://github.com/expressjs/session) to learn more about the available options. Look at the [express-session documentation](https://github.com/expressjs/session) to learn more about the available options.
### Creating Handlers ### Creating Handlers
Create a directory called the `handlers` at the project's root. This is the directory where we will be placing all the route-handling functions. Create a directory called the `handlers` at the project's root. This is the directory where we will be placing all the route-handling functions.
Now let's create the homepage route, which will show the welcome message and a link to log out for the logged-in users and redirect to the login screen for the logged-out users. Create a file at `handlers/home.js` with the following content. Now let's create the homepage route, which will show the welcome message and a link to log out for the logged-in users and redirect to the login screen for the logged-out users. Create a file at `handlers/home.js` with the following content.
@ -105,14 +119,14 @@ module.exports = function HomeHandler(req, res) {
return res.redirect('/login'); return res.redirect('/login');
} }
res.setHeader('Content-Type', 'text/HTML') res.setHeader('Content-Type', 'text/HTML');
res.write(` res.write(`
<h1>Welcome back ${req.session.userid}</h1> <h1>Welcome back ${req.session.userid}</h1>
<a href="/logout">Logout</a> <a href="/logout">Logout</a>
`); `);
res.end() res.end();
} };
``` ```
At the top of this function, you will notice the check `req.session.userid`. `req.session` is automatically populated using the session cookie by the `express-session` middleware that we registered earlier. `req.session.userid` is one of the data fields that we will set to store the `userid` of the logged in user. At the top of this function, you will notice the check `req.session.userid`. `req.session` is automatically populated using the session cookie by the `express-session` middleware that we registered earlier. `req.session.userid` is one of the data fields that we will set to store the `userid` of the logged in user.
@ -133,7 +147,7 @@ module.exports = function LoginHandler(req, res) {
return res.redirect('/'); return res.redirect('/');
} }
res.setHeader('Content-Type', 'text/HTML') res.setHeader('Content-Type', 'text/HTML');
res.write(` res.write(`
<h1>Login</h1> <h1>Login</h1>
<form method="post" action="/process-login"> <form method="post" action="/process-login">
@ -144,8 +158,9 @@ module.exports = function LoginHandler(req, res) {
`); `);
res.end(); res.end();
} };
``` ```
Again, at the top of the function, we are simply checking if we have `userid` in the session (which means the user is logged in). If the user is logged in, we redirect them to the homepage; if not, we show the login screen. In the login form, we have the method of `post`, and we submit the form to `/process-login`. Please note that, for the sake of simplicity, we have a simple HTML string returned in the response, but in a real-world application, you will probably have a separate view file. Again, at the top of the function, we are simply checking if we have `userid` in the session (which means the user is logged in). If the user is logged in, we redirect them to the homepage; if not, we show the login screen. In the login form, we have the method of `post`, and we submit the form to `/process-login`. Please note that, for the sake of simplicity, we have a simple HTML string returned in the response, but in a real-world application, you will probably have a separate view file.
Let's first register this page and then implement `/process-login` endpoint. Open the `index.js` file from the root of the project and register the following route: Let's first register this page and then implement `/process-login` endpoint. Open the `index.js` file from the root of the project and register the following route:
@ -173,7 +188,7 @@ module.exports = function processLogin(req, res) {
As you can see, we are simply checking that the username and password should both be `admin` and `admin` for a user to authenticate successfully. Upon finding valid credentials, we set the `userid` in the session by updating `req.session.userid`. Similarly, you can set any data in the session. For example, if we wanted to store the user role, we would do the following: As you can see, we are simply checking that the username and password should both be `admin` and `admin` for a user to authenticate successfully. Upon finding valid credentials, we set the `userid` in the session by updating `req.session.userid`. Similarly, you can set any data in the session. For example, if we wanted to store the user role, we would do the following:
```javascript ```javascript
req.session.role = 'admin' req.session.role = 'admin';
``` ```
And later access this value out of the session anywhere in the subsequent requests. And later access this value out of the session anywhere in the subsequent requests.
@ -192,7 +207,7 @@ Finally, we have the logout functionality. Create a file at `handlers/logout.js`
module.exports = function Logout(req, res) { module.exports = function Logout(req, res) {
req.session.destroy(); req.session.destroy();
res.redirect('/'); res.redirect('/');
} };
``` ```
We reset the session by calling `req.session.destroy()` and then redirecting the user to the homepage. Register the logout handler in the `index.js` file using the following: We reset the session by calling `req.session.destroy()` and then redirecting the user to the homepage. Register the logout handler in the `index.js` file using the following:
@ -204,6 +219,7 @@ app.get('/logout', LogoutHandler);
``` ```
## Running the Application ## Running the Application
Open the `package.json` file and register the `start` script as follows: Open the `package.json` file and register the `start` script as follows:
```javascript ```javascript

@ -2,22 +2,22 @@
title: "Guide to Let's Encrypt SSL Setup" title: "Guide to Let's Encrypt SSL Setup"
description: "Learn how to protect your website using Let's Encrypt SSL Certificates." description: "Learn how to protect your website using Let's Encrypt SSL Certificates."
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Guide to Let's Encrypt SSL Setup - roadmap.sh" title: "Guide to Let's Encrypt SSL Setup - roadmap.sh"
description: "Learn how to protect your website using Let's Encrypt SSL Certificates." description: "Learn how to protect your website using Let's Encrypt SSL Certificates."
isNew: true isNew: true
type: "textual" type: 'textual'
date: 2023-03-13 date: 2023-03-13
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
In this tutorial, I will guide you on creating a free Let's Encrypt SSL certificate for your website that gets automatically renewed. This process requires minimal to no configuration on your part. Let's get started! In this tutorial, I will guide you on creating a free Let's Encrypt SSL certificate for your website that gets automatically renewed. This process requires minimal to no configuration on your part. Let's get started!
@ -80,13 +80,13 @@ SSL certificate generated using certbot is valid for 3 months; after which you n
For the renewal to work, you need to have a cronjob or a systemd timer set up. To check if the automatic renewal is active, you can use one of two methods: For the renewal to work, you need to have a cronjob or a systemd timer set up. To check if the automatic renewal is active, you can use one of two methods:
* Check cronjob to see if there is a certbot renewal cron job registered by running the following command: - Check cronjob to see if there is a certbot renewal cron job registered by running the following command:
```shell ```shell
sudo crontab -l sudo crontab -l
``` ```
* If you don't find the cron job registered, check the systemd timer by running the following command. - If you don't find the cron job registered, check the systemd timer by running the following command.
```shell ```shell
sudo systemctl list-timers sudo systemctl list-timers

@ -1,22 +1,22 @@
--- ---
title: "Single Command Database Setup" title: 'Single Command Database Setup'
description: "Learn how to run MySQL, PostgreSQL, or MongoDB in Docker with single Command" description: 'Learn how to run MySQL, PostgreSQL, or MongoDB in Docker with single Command'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Single Command Database Setup - roadmap.sh" title: 'Single Command Database Setup - roadmap.sh'
description: "Learn how to run MySQL, PostgreSQL, or MongoDB in Docker with single Command" description: 'Learn how to run MySQL, PostgreSQL, or MongoDB in Docker with single Command'
isNew: true isNew: true
type: "textual" type: 'textual'
date: 2023-02-27 date: 2023-02-27
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
When you are working on a backend application, you are likely to need a database. You can either install it on your machine or use a Docker container. I prefer to use Docker containers because it is easier to setup and doesn't pollute my machine with unnecessary dependencies. When you are working on a backend application, you are likely to need a database. You can either install it on your machine or use a Docker container. I prefer to use Docker containers because it is easier to setup and doesn't pollute my machine with unnecessary dependencies.

@ -1,24 +1,23 @@
--- ---
title: "SSL vs TLS vs SSH" title: 'SSL vs TLS vs SSH'
description: "Quick tidbit on the differences between SSL, TLS, HTTPS and SSH" description: 'Quick tidbit on the differences between SSL, TLS, HTTPS and SSH'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "SSL vs TLS vs SSH - roadmap.sh" title: 'SSL vs TLS vs SSH - roadmap.sh'
description: "Quick tidbit on the differences between SSL, TLS, HTTPS and SSH" description: 'Quick tidbit on the differences between SSL, TLS, HTTPS and SSH'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-04-22 date: 2021-04-22
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![SSL vs TLS vs HTTPs vs SSH](/guides/ssl-tls-https-ssh.png)](/guides/ssl-tls-https-ssh.png) [![SSL vs TLS vs HTTPs vs SSH](/guides/ssl-tls-https-ssh.png)](/guides/ssl-tls-https-ssh.png)

@ -1,24 +1,23 @@
--- ---
title: "SSO — Single Sign On" title: 'SSO — Single Sign On'
description: "Learn the basics of SAML and understand how does Single Sign On work." description: 'Learn the basics of SAML and understand how does Single Sign On work.'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "SSO — Single Sign On - roadmap.sh" title: 'SSO — Single Sign On - roadmap.sh'
description: "Learn the basics of SAML and understand how does Single Sign On work." description: 'Learn the basics of SAML and understand how does Single Sign On work.'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-07-01 date: 2021-07-01
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![SSO](/guides/sso.png)](/guides/sso.png) [![SSO](/guides/sso.png)](/guides/sso.png)

@ -1,24 +1,23 @@
--- ---
title: "Token Based Authentication" title: 'Token Based Authentication'
description: "Understand what is token based authentication and how it is implemented" description: 'Understand what is token based authentication and how it is implemented'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Token Based Authentication - roadmap.sh" title: 'Token Based Authentication - roadmap.sh'
description: "Understand what is token based authentication and how it is implemented" description: 'Understand what is token based authentication and how it is implemented'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-06-02 date: 2021-06-02
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![Token based Authentication](/guides/token-authentication.png)](/guides/token-authentication.png) [![Token based Authentication](/guides/token-authentication.png)](/guides/token-authentication.png)

@ -1,26 +1,26 @@
--- ---
title: "Building a BitTorrent Client" title: 'Building a BitTorrent Client'
description: "Learn everything you need to know about BitTorrent by writing a client in Go" description: 'Learn everything you need to know about BitTorrent by writing a client in Go'
author: author:
name: "Jesse Li" name: 'Jesse Li'
url: "https://twitter.com/__jesse_li" url: 'https://twitter.com/__jesse_li'
imageUrl: "/authors/jesse.png" imageUrl: '/authors/jesse.png'
seo: seo:
title: "Building a BitTorrent Client - roadmap.sh" title: 'Building a BitTorrent Client - roadmap.sh'
description: "Learn everything you need to know about BitTorrent by writing a client in Go" description: 'Learn everything you need to know about BitTorrent by writing a client in Go'
isNew: false isNew: false
type: "textual" type: 'textual'
date: 2021-01-17 date: 2021-01-17
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
BitTorrent is a protocol for downloading and distributing files across the Internet. In contrast with the traditional client/server relationship, in which downloaders connect to a central server (for example: watching a movie on Netflix, or loading the web page you're reading now), participants in the BitTorrent network, called **peers**, download pieces of files from *each other*—this is what makes it a **peer-to-peer** protocol. In this article we will investigate how this works, and build our own client that can find peers and exchange data between them. BitTorrent is a protocol for downloading and distributing files across the Internet. In contrast with the traditional client/server relationship, in which downloaders connect to a central server (for example: watching a movie on Netflix, or loading the web page you're reading now), participants in the BitTorrent network, called **peers**, download pieces of files from _each other_—this is what makes it a **peer-to-peer** protocol. In this article we will investigate how this works, and build our own client that can find peers and exchange data between them.
![diagram showing the difference between client/server (all clients connecting to one server) and peer-to-peer (peers connecting to each other) relationships](/guides/torrent-client/client-server-p2p.png) ![diagram showing the difference between client/server (all clients connecting to one server) and peer-to-peer (peers connecting to each other) relationships](/guides/torrent-client/client-server-p2p.png)
@ -29,6 +29,7 @@ The protocol evolved organically over the past 20 years, and various people and
I'll be using a [Debian ISO](https://cdimage.debian.org/debian-cd/current/amd64/bt-cd/#indexlist) file as my guinea pig because it's big, but not huge, at 350MB. As a popular Linux distribution, there will be lots of fast and cooperative peers for us to connect to. And we'll avoid the legal and ethical issues related to downloading pirated content. I'll be using a [Debian ISO](https://cdimage.debian.org/debian-cd/current/amd64/bt-cd/#indexlist) file as my guinea pig because it's big, but not huge, at 350MB. As a popular Linux distribution, there will be lots of fast and cooperative peers for us to connect to. And we'll avoid the legal and ethical issues related to downloading pirated content.
## Finding peers ## Finding peers
Here’s a problem: we want to download a file with BitTorrent, but it’s a peer-to-peer protocol and we have no idea where to find peers to download it from. This is a lot like moving to a new city and trying to make friends—maybe we’ll hit up a local pub or a meetup group! Centralized locations like these are the big idea behind trackers, which are central servers that introduce peers to each other. They’re just web servers running over HTTP, and you can find Debian’s at http://bttracker.debian.org:6969/ Here’s a problem: we want to download a file with BitTorrent, but it’s a peer-to-peer protocol and we have no idea where to find peers to download it from. This is a lot like moving to a new city and trying to make friends—maybe we’ll hit up a local pub or a meetup group! Centralized locations like these are the big idea behind trackers, which are central servers that introduce peers to each other. They’re just web servers running over HTTP, and you can find Debian’s at http://bttracker.debian.org:6969/
![illustration of a desktop computer and laptop sitting at a pub](/guides/torrent-client/trackers.png) ![illustration of a desktop computer and laptop sitting at a pub](/guides/torrent-client/trackers.png)
@ -36,16 +37,16 @@ Here’s a problem: we want to download a file with BitTorrent, but it’s a pee
Of course, these central servers are liable to get raided by the feds if they facilitate peers exchanging illegal content. You may remember reading about trackers like TorrentSpy, Popcorn Time, and KickassTorrents getting seized and shut down. New methods cut out the middleman by making even **peer discovery** a distributed process. We won't be implementing them, but if you're interested, some terms you can research are **DHT**, **PEX**, and **magnet links**. Of course, these central servers are liable to get raided by the feds if they facilitate peers exchanging illegal content. You may remember reading about trackers like TorrentSpy, Popcorn Time, and KickassTorrents getting seized and shut down. New methods cut out the middleman by making even **peer discovery** a distributed process. We won't be implementing them, but if you're interested, some terms you can research are **DHT**, **PEX**, and **magnet links**.
### Parsing a .torrent file ### Parsing a .torrent file
A .torrent file describes the contents of a torrentable file and information for connecting to a tracker. It's all we need in order to kickstart the process of downloading a torrent. Debian's .torrent file looks like this: A .torrent file describes the contents of a torrentable file and information for connecting to a tracker. It's all we need in order to kickstart the process of downloading a torrent. Debian's .torrent file looks like this:
```markdown ```markdown
d8:announce41:http://bttracker.debian.org:6969/announce7:comment35:"Debian CD from cdimage.debian.org"13:creation datei1573903810e9:httpseedsl145:https://cdimage.debian.org/cdimage/release/10.2.0//srv/cdbuilder.debian.org/dst/deb-cd/weekly-builds/amd64/iso-cd/debian-10.2.0-amd64-netinst.iso145:https://cdimage.debian.org/cdimage/archive/10.2.0//srv/cdbuilder.debian.org/dst/deb-cd/weekly-builds/amd64/iso-cd/debian-10.2.0-amd64-netinst.isoe4:infod6:lengthi351272960e4:name31:debian-10.2.0-amd64-netinst.iso12:piece lengthi262144e6:pieces26800:<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PS<EFBFBD>^<EFBFBD><EFBFBD> (binary blob of the hashes of each piece)ee d8:announce41:http://bttracker.debian.org:6969/announce7:comment35:"Debian CD from cdimage.debian.org"13:creation datei1573903810e9:httpseedsl145:https://cdimage.debian.org/cdimage/release/10.2.0//srv/cdbuilder.debian.org/dst/deb-cd/weekly-builds/amd64/iso-cd/debian-10.2.0-amd64-netinst.iso145:https://cdimage.debian.org/cdimage/archive/10.2.0//srv/cdbuilder.debian.org/dst/deb-cd/weekly-builds/amd64/iso-cd/debian-10.2.0-amd64-netinst.isoe4:infod6:lengthi351272960e4:name31:debian-10.2.0-amd64-netinst.iso12:piece lengthi262144e6:pieces26800:<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PS<EFBFBD>^<EFBFBD><EFBFBD> (binary blob of the hashes of each piece)ee
``` ```
That mess is encoded in a format called **Bencode** (pronounced *bee-encode*), and we'll need to decode it. That mess is encoded in a format called **Bencode** (pronounced _bee-encode_), and we'll need to decode it.
Bencode can encode roughly the same types of structures as JSON—strings, integers, lists, and dictionaries. Bencoded data is not as human-readable/writable as JSON, but it can efficiently handle binary data and it's really simple to parse from a stream. Strings come with a length prefix, and look like `4:spam`. Integers go between *start* and *end* markers, so `7` would encode to `i7e`. Lists and dictionaries work in a similar way: `l4:spami7ee` represents `['spam', 7]`, while `d4:spami7ee` means `{spam: 7}`.
Bencode can encode roughly the same types of structures as JSON—strings, integers, lists, and dictionaries. Bencoded data is not as human-readable/writable as JSON, but it can efficiently handle binary data and it's really simple to parse from a stream. Strings come with a length prefix, and look like `4:spam`. Integers go between _start_ and _end_ markers, so `7` would encode to `i7e`. Lists and dictionaries work in a similar way: `l4:spami7ee` represents `['spam', 7]`, while `d4:spami7ee` means `{spam: 7}`.
In a prettier format, our .torrent file looks like this: In a prettier format, our .torrent file looks like this:
@ -71,7 +72,7 @@ d
e e
``` ```
In this file, we can spot the URL of the tracker, the creation date (as a Unix timestamp), the name and size of the file, and a big binary blob containing the SHA-1 hashes of each **piece**, which are equally-sized parts of the file we want to download. The exact size of a piece varies between torrents, but they are usually somewhere between 256KB and 1MB. This means that a large file might be made up of *thousands* of pieces. We'll download these pieces from our peers, check them against the hashes from our torrent file, assemble them together, and boom, we've got a file! In this file, we can spot the URL of the tracker, the creation date (as a Unix timestamp), the name and size of the file, and a big binary blob containing the SHA-1 hashes of each **piece**, which are equally-sized parts of the file we want to download. The exact size of a piece varies between torrents, but they are usually somewhere between 256KB and 1MB. This means that a large file might be made up of _thousands_ of pieces. We'll download these pieces from our peers, check them against the hashes from our torrent file, assemble them together, and boom, we've got a file!
!["illustration of a file being cut with scissors into multiple pieces, starting with piece 0](/guides/torrent-client/pieces.png) !["illustration of a file being cut with scissors into multiple pieces, starting with piece 0](/guides/torrent-client/pieces.png)
@ -129,6 +130,7 @@ func (bto *bencodeTorrent) toTorrentFile() (*TorrentFile, error) {
``` ```
### Retrieving peers from the tracker ### Retrieving peers from the tracker
Now that we have information about the file and its tracker, let's talk to the tracker to **announce** our presence as a peer and to retrieve a list of other peers. We just need to make a GET request to the `announce` URL supplied in the .torrent file, with a few query parameters: Now that we have information about the file and its tracker, let's talk to the tracker to **announce** our presence as a peer and to retrieve a list of other peers. We just need to make a GET request to the `announce` URL supplied in the .torrent file, with a few query parameters:
```go ```go
@ -153,12 +155,13 @@ func (t *TorrentFile) buildTrackerURL(peerID [20]byte, port uint16) (string, err
The important ones: The important ones:
* **info_hash**: Identifies the *file* we're trying to download. It's the infohash we calculated earlier from the bencoded `info` dict. The tracker will use this to figure out which peers to show us. - **info_hash**: Identifies the _file_ we're trying to download. It's the infohash we calculated earlier from the bencoded `info` dict. The tracker will use this to figure out which peers to show us.
* **peer_id**: A 20 byte name to identify *ourselves* to trackers and peers. We'll just generate 20 random bytes for this. Real BitTorrent clients have IDs like `-TR2940-k8hj0wgej6ch` which identify the client software and version—in this case, TR2940 stands for Transmission client 2.94. - **peer_id**: A 20 byte name to identify _ourselves_ to trackers and peers. We'll just generate 20 random bytes for this. Real BitTorrent clients have IDs like `-TR2940-k8hj0wgej6ch` which identify the client software and version—in this case, TR2940 stands for Transmission client 2.94.
![a file with a name tag saying 'info_hash' and a person with a name tag 'peer_id'](/guides/torrent-client/info-hash-peer-id.png) ![a file with a name tag saying 'info_hash' and a person with a name tag 'peer_id'](/guides/torrent-client/info-hash-peer-id.png)
### Parsing the tracker response ### Parsing the tracker response
We get back a bencoded response: We get back a bencoded response:
```markdown ```markdown
@ -202,13 +205,15 @@ func Unmarshal(peersBin []byte) ([]Peer, error) {
``` ```
## Downloading from peers ## Downloading from peers
Now that we have a list of peers, it's time to connect with them and start downloading pieces! We can break down the process into a few steps. For each peer, we want to: Now that we have a list of peers, it's time to connect with them and start downloading pieces! We can break down the process into a few steps. For each peer, we want to:
1. Start a TCP connection with the peer. This is like starting a phone call. 1. Start a TCP connection with the peer. This is like starting a phone call.
2. Complete a two-way BitTorrent **handshake**. *"Hello?" "Hello."* 2. Complete a two-way BitTorrent **handshake**. _"Hello?" "Hello."_
3. Exchange **messages** to download **pieces**. *"I'd like piece #231 please."* 3. Exchange **messages** to download **pieces**. _"I'd like piece #231 please."_
## Start a TCP connection ## Start a TCP connection
```go ```go
conn, err := net.DialTimeout("tcp", peer.String(), 3*time.Second) conn, err := net.DialTimeout("tcp", peer.String(), 3*time.Second)
if err != nil { if err != nil {
@ -219,11 +224,12 @@ if err != nil {
I set a timeout so that I don't waste too much time on peers that aren't going to let me connect. For the most part, it's a pretty standard TCP connection. I set a timeout so that I don't waste too much time on peers that aren't going to let me connect. For the most part, it's a pretty standard TCP connection.
### Complete the handshake ### Complete the handshake
We've just set up a connection with a peer, but we want do a handshake to validate our assumptions that the peer We've just set up a connection with a peer, but we want do a handshake to validate our assumptions that the peer
* can communicate using the BitTorrent protocol - can communicate using the BitTorrent protocol
* is able to understand and respond to our messages - is able to understand and respond to our messages
* has the file that we want, or at least knows what we're talking about - has the file that we want, or at least knows what we're talking about
![Two computers communicating. One asks 'do you speak BitTorrent and have this file?' and the other replies 'I speak BitTorrent and have that file'](/guides/torrent-client/handshake.png) ![Two computers communicating. One asks 'do you speak BitTorrent and have this file?' and the other replies 'I speak BitTorrent and have that file'](/guides/torrent-client/handshake.png)
@ -241,7 +247,7 @@ Put together, a handshake string might look like this:
\x13BitTorrent protocol\x00\x00\x00\x00\x00\x00\x00\x00\x86\xd4\xc8\x00\x24\xa4\x69\xbe\x4c\x50\xbc\x5a\x10\x2c\xf7\x17\x80\x31\x00\x74-TR2940-k8hj0wgej6ch \x13BitTorrent protocol\x00\x00\x00\x00\x00\x00\x00\x00\x86\xd4\xc8\x00\x24\xa4\x69\xbe\x4c\x50\xbc\x5a\x10\x2c\xf7\x17\x80\x31\x00\x74-TR2940-k8hj0wgej6ch
``` ```
After we send a handshake to our peer, we should receive a handshake back in the same format. The infohash we get back should match the one we sent so that we know that we're talking about the same file. If everything goes as planned, we're good to go. If not, we can sever the connection because there's something wrong. *"Hello?" "这是谁? 你想要什么?" "Okay, wow, wrong number."* After we send a handshake to our peer, we should receive a handshake back in the same format. The infohash we get back should match the one we sent so that we know that we're talking about the same file. If everything goes as planned, we're good to go. If not, we can sever the connection because there's something wrong. _"Hello?" "这是谁? 你想要什么?" "Okay, wow, wrong number."_
In our code, let's make a struct to represent a handshake, and write a few methods for serializing and reading them: In our code, let's make a struct to represent a handshake, and write a few methods for serializing and reading them:
@ -273,6 +279,7 @@ func Read(r io.Reader) (*Handshake, error) {
``` ```
### Send and receive messages ### Send and receive messages
Once we've completed the initial handshake, we can send and receive **messages**. Well, not quite—if the other peer isn't ready to accept messages, we can't send any until they tell us they're ready. In this state, we're considered **choked** by the other peer. They'll send us an **unchoke** message to let us know that we can begin asking them for data. By default, we assume that we're choked until proven otherwise. Once we've completed the initial handshake, we can send and receive **messages**. Well, not quite—if the other peer isn't ready to accept messages, we can't send any until they tell us they're ready. In this state, we're considered **choked** by the other peer. They'll send us an **unchoke** message to let us know that we can begin asking them for data. By default, we assume that we're choked until proven otherwise.
Once we've been unchoked, we can then begin sending **requests** for pieces, and they can send us messages back containing pieces. Once we've been unchoked, we can then begin sending **requests** for pieces, and they can send us messages back containing pieces.
@ -280,6 +287,7 @@ Once we've been unchoked, we can then begin sending **requests** for pieces, and
!["A cartoon in which person 1 says 'hello I would like piece number—' and person 2 grabs him by the neck and says '00 00 00 01 00 (choke)'](/guides/torrent-client/choke.png) !["A cartoon in which person 1 says 'hello I would like piece number—' and person 2 grabs him by the neck and says '00 00 00 01 00 (choke)'](/guides/torrent-client/choke.png)
#### Interpreting messages #### Interpreting messages
A message has a length, an **ID** and a **payload**. On the wire, it looks like: A message has a length, an **ID** and a **payload**. On the wire, it looks like:
![A message with 4 byte for the length, 1 byte for ID, and an optional payload](/guides/torrent-client/message.png) ![A message with 4 byte for the length, 1 byte for ID, and an optional payload](/guides/torrent-client/message.png)
@ -356,11 +364,12 @@ func Read(r io.Reader) (*Message, error) {
``` ```
#### Bitfields #### Bitfields
One of the most interesting types of message is the **bitfield**, which is a data structure that peers use to efficiently encode which pieces they are able to send us. A bitfield looks like a byte array, and to check which pieces they have, we just need to look at the positions of the *bits* set to 1. You can think of it like the digital equivalent of a coffee shop loyalty card. We start with a blank card of all `0`, and flip bits to `1` to mark their positions as "stamped."
One of the most interesting types of message is the **bitfield**, which is a data structure that peers use to efficiently encode which pieces they are able to send us. A bitfield looks like a byte array, and to check which pieces they have, we just need to look at the positions of the _bits_ set to 1. You can think of it like the digital equivalent of a coffee shop loyalty card. We start with a blank card of all `0`, and flip bits to `1` to mark their positions as "stamped."
![a coffee shop loyalty card with eight slots, with stamps on the first four slots and a stamp on the second to last slot, represented as 11110010](/guides/torrent-client/bitfield.png) ![a coffee shop loyalty card with eight slots, with stamps on the first four slots and a stamp on the second to last slot, represented as 11110010](/guides/torrent-client/bitfield.png)
By working with *bits* instead of *bytes*, this data structure is super compact. We can stuff information about eight pieces in the space of a single byte—the size of a `bool`. The tradeoff is that accessing values becomes a little more tricky. The smallest unit of memory that computers can address are bytes, so to get to our bits, we have to do some bitwise manipulation: By working with _bits_ instead of _bytes_, this data structure is super compact. We can stuff information about eight pieces in the space of a single byte—the size of a `bool`. The tradeoff is that accessing values becomes a little more tricky. The smallest unit of memory that computers can address are bytes, so to get to our bits, we have to do some bitwise manipulation:
```go ```go
// A Bitfield represents the pieces that a peer has // A Bitfield represents the pieces that a peer has
@ -382,9 +391,11 @@ func (bf Bitfield) SetPiece(index int) {
``` ```
### Putting it all together ### Putting it all together
We now have all the tools we need to download a torrent: we have a list of peers obtained from the tracker, and we can communicate with them by dialing a TCP connection, initiating a handshake, and sending and receiving messages. Our last big problems are handling the **concurrency** involved in talking to multiple peers at once, and managing the **state** of our peers as we interact with them. These are both classically Hard problems. We now have all the tools we need to download a torrent: we have a list of peers obtained from the tracker, and we can communicate with them by dialing a TCP connection, initiating a handshake, and sending and receiving messages. Our last big problems are handling the **concurrency** involved in talking to multiple peers at once, and managing the **state** of our peers as we interact with them. These are both classically Hard problems.
#### Managing concurrency: channels as queues #### Managing concurrency: channels as queues
In Go, we [share memory by communicating](https://blog.golang.org/share-memory-by-communicating), and we can think of a Go channel as a cheap thread-safe queue. In Go, we [share memory by communicating](https://blog.golang.org/share-memory-by-communicating), and we can think of a Go channel as a cheap thread-safe queue.
We'll set up two channels to synchronize our concurrent workers: one for dishing out work (pieces to download) between peers, and another for collecting downloaded pieces. As downloaded pieces come in through the results channel, we can copy them into a buffer to start assembling our complete file. We'll set up two channels to synchronize our concurrent workers: one for dishing out work (pieces to download) between peers, and another for collecting downloaded pieces. As downloaded pieces come in through the results channel, we can copy them into a buffer to start assembling our complete file.
@ -460,6 +471,7 @@ func (t *Torrent) startDownloadWorker(peer peers.Peer, workQueue chan *pieceWork
``` ```
#### Managing state #### Managing state
We'll keep track of each peer in a struct, and modify that struct as we read messages. It'll include data like how much we've downloaded from the peer, how much we've requested from them, and whether we're choked. If we wanted to scale this further, we could formalize this as a finite state machine. But a struct and a switch are good enough for now. We'll keep track of each peer in a struct, and modify that struct as we read messages. It'll include data like how much we've downloaded from the peer, how much we've requested from them, and whether we're choked. If we wanted to scale this further, we could formalize this as a finite state machine. But a struct and a switch are good enough for now.
```go ```go
@ -492,11 +504,13 @@ func (state *pieceProgress) readMessage() error {
``` ```
#### Time to make requests! #### Time to make requests!
Files, pieces, and piece hashes aren't the full story—we can go further by breaking down pieces into **blocks**. A block is a part of a piece, and we can fully define a block by the **index** of the piece it's part of, its byte **offset** within the piece, and its **length**. When we make requests for data from peers, we are actually requesting *blocks*. A block is usually 16KB large, meaning that a single 256 KB piece might actually require 16 requests.
Files, pieces, and piece hashes aren't the full story—we can go further by breaking down pieces into **blocks**. A block is a part of a piece, and we can fully define a block by the **index** of the piece it's part of, its byte **offset** within the piece, and its **length**. When we make requests for data from peers, we are actually requesting _blocks_. A block is usually 16KB large, meaning that a single 256 KB piece might actually require 16 requests.
A peer is supposed to sever the connection if they receive a request for a block larger than 16KB. However, based on my experience, they're often perfectly happy to satisfy requests up to 128KB. I only got moderate gains in overall speed with larger block sizes, so it's probably better to stick with the spec. A peer is supposed to sever the connection if they receive a request for a block larger than 16KB. However, based on my experience, they're often perfectly happy to satisfy requests up to 128KB. I only got moderate gains in overall speed with larger block sizes, so it's probably better to stick with the spec.
#### Pipelining #### Pipelining
Network round-trips are expensive, and requesting each block one by one will absolutely thank the performance of our download. Therefore, it's important to **pipeline** our requests such that we keep up a constant pressure of some number of unfulfilled requests. This can increase the throughput of our connection by an order of magnitude. Network round-trips are expensive, and requesting each block one by one will absolutely thank the performance of our download. Therefore, it's important to **pipeline** our requests such that we keep up a constant pressure of some number of unfulfilled requests. This can increase the throughput of our connection by an order of magnitude.
![Two email threads simulating peer connections. The thread on the left shows a request followed by a reply, repeated three times. The thread on the left sends three requests, and receives three replies in quick succession.](/guides/torrent-client/pipelining.png) ![Two email threads simulating peer connections. The thread on the left shows a request followed by a reply, repeated three times. The thread on the left sends three requests, and receives three replies in quick succession.](/guides/torrent-client/pipelining.png)
@ -552,6 +566,7 @@ func attemptDownloadPiece(c *client.Client, pw *pieceWork) ([]byte, error) {
``` ```
#### main.go #### main.go
This is a short one. We're almost there. This is a short one. We're almost there.
```go ```go
@ -583,4 +598,5 @@ func main() {
<script id="asciicast-xqRSB0Jec8RN91Zt89rbb9PcL" src="https://asciinema.org/a/xqRSB0Jec8RN91Zt89rbb9PcL.js" async></script> <script id="asciicast-xqRSB0Jec8RN91Zt89rbb9PcL" src="https://asciinema.org/a/xqRSB0Jec8RN91Zt89rbb9PcL.js" async></script>
## This isn't the full story ## This isn't the full story
For brevity, I included only a few of the important snippets of code. Notably, I left out all the glue code, parsing, unit tests, and the boring parts that build character. View my [full implementation](https://github.com/veggiedefender/torrent-client) if you're interested. For brevity, I included only a few of the important snippets of code. Notably, I left out all the glue code, parsing, unit tests, and the boring parts that build character. View my [full implementation](https://github.com/veggiedefender/torrent-client) if you're interested.

@ -1,24 +1,23 @@
--- ---
title: "Unfamiliar Codebase" title: 'Unfamiliar Codebase'
description: "Tips on getting familiar with an unfamiliar codebase" description: 'Tips on getting familiar with an unfamiliar codebase'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Unfamiliar Codebase - roadmap.sh" title: 'Unfamiliar Codebase - roadmap.sh'
description: "Tips on getting familiar with an unfamiliar codebase" description: 'Tips on getting familiar with an unfamiliar codebase'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-05-04 date: 2021-05-04
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![Unfamiliar Codebase](/guides/unfamiliar-codebase.png)](/guides/unfamiliar-codebase.png) [![Unfamiliar Codebase](/guides/unfamiliar-codebase.png)](/guides/unfamiliar-codebase.png)

@ -1,24 +1,23 @@
--- ---
title: "What are Web Vitals?" title: 'What are Web Vitals?'
description: "Learn what are the core web vitals and how to measure them." description: 'Learn what are the core web vitals and how to measure them.'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "What are Web Vitals? - roadmap.sh" title: 'What are Web Vitals? - roadmap.sh'
description: "Learn what are the core web vitals and how to measure them." description: 'Learn what are the core web vitals and how to measure them.'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-09-05 date: 2021-09-05
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![Web Vitals](/guides/web-vitals.png)](/guides/web-vitals.png) [![Web Vitals](/guides/web-vitals.png)](/guides/web-vitals.png)

@ -1,34 +1,34 @@
--- ---
title: "How does the internet work?" title: 'How does the internet work?'
description: "Learn the basics of internet and everything involved with this short video series" description: 'Learn the basics of internet and everything involved with this short video series'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "How does the internet work? - roadmap.sh" title: 'How does the internet work? - roadmap.sh'
description: "Learn the basics of internet and everything involved with this short video series" description: 'Learn the basics of internet and everything involved with this short video series'
isNew: false isNew: false
type: "textual" type: 'textual'
date: 2021-02-29 date: 2021-02-29
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
Since the explosive growth of web-based applications, every developer stands to benefit from understanding how the Internet works. Through this article and its accompanying introductory series of short videos about the Internet from [code.org](https://code.org), you will learn the basics of the Internet and how it works. After going through this article, you will be able to answer the following questions: Since the explosive growth of web-based applications, every developer stands to benefit from understanding how the Internet works. Through this article and its accompanying introductory series of short videos about the Internet from [code.org](https://code.org), you will learn the basics of the Internet and how it works. After going through this article, you will be able to answer the following questions:
* What is the Internet? - What is the Internet?
* How does the information move on the internet? - How does the information move on the internet?
* How do the networks talk to each other and the protocols involved? - How do the networks talk to each other and the protocols involved?
* What's the relationship between packets, routers, and reliability? - What's the relationship between packets, routers, and reliability?
* HTTP and the HTML – How are you viewing this webpage in your browser? - HTTP and the HTML – How are you viewing this webpage in your browser?
* How is the information transfer on the internet made secure? - How is the information transfer on the internet made secure?
* What is cybersecurity and what are some common internet crimes? - What is cybersecurity and what are some common internet crimes?
## What is the Internet? ## What is the Internet?
@ -38,7 +38,6 @@ In the video below, Vint Cerf, one of the "fathers of the internet," explains th
<iframe class="w-full aspect-video mb-5" width="100%" height="400" src="https://www.youtube.com/embed/Dxcc6ycZ73M" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> <iframe class="w-full aspect-video mb-5" width="100%" height="400" src="https://www.youtube.com/embed/Dxcc6ycZ73M" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## Wires, Cables, and Wi-Fi ## Wires, Cables, and Wi-Fi
Information on the Internet moves from one computer to another in the form of bits over various mediums, including Ethernet cables, fiber optic cables, and wireless signals (i.e., radio waves). Information on the Internet moves from one computer to another in the form of bits over various mediums, including Ethernet cables, fiber optic cables, and wireless signals (i.e., radio waves).

@ -1,24 +1,23 @@
--- ---
title: "SLIs, SLOs and SLAs" title: 'SLIs, SLOs and SLAs'
description: "Learn what are different indicators for performance identification of any service." description: 'Learn what are different indicators for performance identification of any service.'
author: author:
name: "Kamran Ahmed" name: 'Kamran Ahmed'
url: "https://twitter.com/kamranahmedse" url: 'https://twitter.com/kamranahmedse'
imageUrl: "/authors/kamranahmedse.jpeg" imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "SLIs, SLOs and SLAs - roadmap.sh" title: 'SLIs, SLOs and SLAs - roadmap.sh'
description: "Learn what are different indicators for performance identification of any service." description: 'Learn what are different indicators for performance identification of any service.'
isNew: false isNew: false
type: "visual" type: 'visual'
date: 2021-08-31 date: 2021-08-31
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "visual-guide" - 'visual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
[![SLI vs SLO vs SLA](/guides/sli-slo-sla.jpeg)](/guides/sli-slo-sla.jpeg) [![SLI vs SLO vs SLA](/guides/sli-slo-sla.jpeg)](/guides/sli-slo-sla.jpeg)

@ -1,34 +1,32 @@
--- ---
title: "Build it and they will come?" title: 'Build it and they will come?'
description: "Why “build it and they will come” alone won’t work anymore" description: 'Why “build it and they will come” alone won’t work anymore'
author: author:
name: "Peter Thaleikis" name: 'Peter Thaleikis'
url: "https://twitter.com/spekulatius1984" url: 'https://twitter.com/spekulatius1984'
imageUrl: "/authors/spekulatius.jpg" imageUrl: '/authors/spekulatius.jpg'
seo: seo:
title: "Build it and they will come? - roadmap.sh" title: 'Build it and they will come? - roadmap.sh'
description: "Why “build it and they will come” alone won’t work anymore" description: 'Why “build it and they will come” alone won’t work anymore'
isNew: false isNew: false
type: "textual" type: 'textual'
date: 2021-05-04 date: 2021-05-04
sitemap: sitemap:
priority: 0.7 priority: 0.7
changefreq: "weekly" changefreq: 'weekly'
tags: tags:
- "guide" - 'guide'
- "textual-guide" - 'textual-guide'
- "guide-sitemap" - 'guide-sitemap'
--- ---
We all have heard the mantra *"build it and they will come"* many times. Stories of people building a startup or project and seemingly stumbling upon a goldmine aren't few, but they aren't the rule. These stories are still the exception in the mass of launched projects and startups. We all have heard the mantra _"build it and they will come"_ many times. Stories of people building a startup or project and seemingly stumbling upon a goldmine aren't few, but they aren't the rule. These stories are still the exception in the mass of launched projects and startups.
Before the [Wright brothers](https://en.wikipedia.org/wiki/Wright_brothers) built their Kitty Hawk, people generally believed heavy objects could not fly - physics simply forbade it. The idea of regularly boarding airplanes as we do it these days was unthinkable. It was considered an unrealistic daydream for humans to ever claim the sky. When the first airplanes took off, people were fascinated, of course. It was a topic people continued to talk about for ages. Technology had made something impossible possible. While the wording "build it and they will come" originated from the movie [Field of Dreams](https://en.wikipedia.org/wiki/Field_of_Dreams), this and similar historic events gave birth to the idea behind it. Before the [Wright brothers](https://en.wikipedia.org/wiki/Wright_brothers) built their Kitty Hawk, people generally believed heavy objects could not fly - physics simply forbade it. The idea of regularly boarding airplanes as we do it these days was unthinkable. It was considered an unrealistic daydream for humans to ever claim the sky. When the first airplanes took off, people were fascinated, of course. It was a topic people continued to talk about for ages. Technology had made something impossible possible. While the wording "build it and they will come" originated from the movie [Field of Dreams](https://en.wikipedia.org/wiki/Field_of_Dreams), this and similar historic events gave birth to the idea behind it.
The engineers' and inventors' dreams came true: spend time doing what you love while success follows magically. The internet and web-standards democratized access to this dream. But with it, the idea behind it faded and became less and less powerful. In 2020, there are very strong signs the popular saying isn't correct anymore. The engineers' and inventors' dreams came true: spend time doing what you love while success follows magically. The internet and web-standards democratized access to this dream. But with it, the idea behind it faded and became less and less powerful. In 2020, there are very strong signs the popular saying isn't correct anymore.
## Why doesn't "build it and they will come" work anymore?
Why doesn't "build it and they will come" work anymore?
-------------------------------------------------------
There are a few reasons for working hard to make "build it and they will come" a thing of the past. This being said, it doesn't mean you can't succeed in building a side-project anymore. You've just got to adjust the way you are building it. There are a few reasons for working hard to make "build it and they will come" a thing of the past. This being said, it doesn't mean you can't succeed in building a side-project anymore. You've just got to adjust the way you are building it.
@ -48,9 +46,7 @@ Besides building is easier than ever before and attention is in short supply, th
Does sound pretty grim for inventors, developers, and engineers? Well, yes and no. We've got to tweak the approach to get in front of the eye of potential users and customers. Does sound pretty grim for inventors, developers, and engineers? Well, yes and no. We've got to tweak the approach to get in front of the eye of potential users and customers.
## How to market your project nowadays?
How to market your project nowadays?
------------------------------------
The very first step to improving the odds of success is [idea validation](https://peterthaleikis.com/business-idea-validation/). While this sounds fairly obvious, many engineers and developers still don't validate their ideas before starting to build the MVP. The result is another stale project and wasted effort. To succeed you need to work on marketing before you start building anything. In the link mentioned before, I describe my approach to validation and collecting useful marketing information at the same time. The very first step to improving the odds of success is [idea validation](https://peterthaleikis.com/business-idea-validation/). While this sounds fairly obvious, many engineers and developers still don't validate their ideas before starting to build the MVP. The result is another stale project and wasted effort. To succeed you need to work on marketing before you start building anything. In the link mentioned before, I describe my approach to validation and collecting useful marketing information at the same time.
@ -78,14 +74,10 @@ Launching seems like this special moment when you release your project into the
Many developers plan to launch their product on a few sites and see where it takes their project from there on. This works well if your product goes viral by luck. A much more sustainable approach is constantly working a little on it. Marketing is most effective if done consistently. That holds true for blogging as well as most other forms of marketing. A simple approach to keep you on the path to marketing your project regularly is subscribing to a free [newsletter with small marketing opportunities](https://wheretopost.email). This way, you are regularly reminded and given bite-sized tasks to complete. Many developers plan to launch their product on a few sites and see where it takes their project from there on. This works well if your product goes viral by luck. A much more sustainable approach is constantly working a little on it. Marketing is most effective if done consistently. That holds true for blogging as well as most other forms of marketing. A simple approach to keep you on the path to marketing your project regularly is subscribing to a free [newsletter with small marketing opportunities](https://wheretopost.email). This way, you are regularly reminded and given bite-sized tasks to complete.
## Closing Words
Closing Words
-------------
I hope the article helped you to wrap your head around the idea that building side-projects alone doesn't solve any issues anymore. If you like what you've just read and want to read more, please consider subscribing to [my newsletter](https://peterthaleikis.com/newsletter). I'll send out the occasional email about interesting new articles or side-projects. I hope the article helped you to wrap your head around the idea that building side-projects alone doesn't solve any issues anymore. If you like what you've just read and want to read more, please consider subscribing to [my newsletter](https://peterthaleikis.com/newsletter). I'll send out the occasional email about interesting new articles or side-projects.
## About the author
About the author
----------------
[Peter Thaleikis](https://peterthaleikis.com/) a software engineer and business owner. He has been developing web applications since around 2000. Before he started his own software development company [Bring Your Own Ideas Ltd.](https://bringyourownideas.com/), he has been a Lead Developer for multiple organizations. [Peter Thaleikis](https://peterthaleikis.com/) a software engineer and business owner. He has been developing web applications since around 2000. Before he started his own software development company [Bring Your Own Ideas Ltd.](https://bringyourownideas.com/), he has been a Lead Developer for multiple organizations.

@ -1,45 +1,45 @@
--- ---
# jsonUrl: "/jsons/roadmaps/android.json" # jsonUrl: "/jsons/roadmaps/android.json"
pdfUrl: "/pdfs/roadmaps/android.pdf" pdfUrl: '/pdfs/roadmaps/android.pdf'
order: 4 order: 4
briefTitle: "Android" briefTitle: 'Android'
briefDescription: "Step by step guide to becoming an Android Developer in 2023" briefDescription: 'Step by step guide to becoming an Android Developer in 2023'
title: "Android Developer" title: 'Android Developer'
description: "Step by step guide to becoming an Android developer in 2023" description: 'Step by step guide to becoming an Android developer in 2023'
hasTopics: false hasTopics: false
schema: schema:
headline: "Android Developer Roadmap" headline: 'Android Developer Roadmap'
description: "Learn how to become a Android Developer with this interactive step by step guide in 2023. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place." description: 'Learn how to become a Android Developer with this interactive step by step guide in 2023. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place.'
imageUrl: "https://roadmap.sh/roadmaps/android.png" imageUrl: 'https://roadmap.sh/roadmaps/android.png'
datePublished: "2023-01-05" datePublished: '2023-01-05'
dateModified: "2023-01-20" dateModified: '2023-01-20'
seo: seo:
title: "Android Developer Roadmap: Learn to become an Android developer" title: 'Android Developer Roadmap: Learn to become an Android developer'
description: "Community driven, articles, resources, guides, interview questions, quizzes for android development. Learn to become a modern Android developer by following the steps, skills, resources and guides listed in this roadmap." description: 'Community driven, articles, resources, guides, interview questions, quizzes for android development. Learn to become a modern Android developer by following the steps, skills, resources and guides listed in this roadmap.'
keywords: keywords:
- "guide to becoming an android developer" - 'guide to becoming an android developer'
- "android developer roadmap" - 'android developer roadmap'
- "android roadmap" - 'android roadmap'
- "become android developer" - 'become android developer'
- "android developer skills" - 'android developer skills'
- "android skills test" - 'android skills test'
- "skills for android development" - 'skills for android development'
- "learn android development" - 'learn android development'
- "what is android" - 'what is android'
- "android quiz" - 'android quiz'
- "android interview questions" - 'android interview questions'
relatedRoadmaps: relatedRoadmaps:
- "frontend" - 'frontend'
- "javascript" - 'javascript'
- "react" - 'react'
- "nodejs" - 'nodejs'
sitemap: sitemap:
priority: 1 priority: 1
changefreq: "monthly" changefreq: 'monthly'
tags: tags:
- "roadmap" - 'roadmap'
- "main-sitemap" - 'main-sitemap'
- "role-roadmap" - 'role-roadmap'
--- ---
The intent of this guide is to give you an idea about the Android development landscape and to help guide your learning if you are confused. Before we start, please note that the roadmap is opinionated, and you might have different opinions than those of the author. Having said that, [we would love to hear your opinions](https://github.com/kamranahmedse/developer-roadmap/issues/new) and incorporate them in the roadmap if suitable. The intent of this guide is to give you an idea about the Android development landscape and to help guide your learning if you are confused. Before we start, please note that the roadmap is opinionated, and you might have different opinions than those of the author. Having said that, [we would love to hear your opinions](https://github.com/kamranahmedse/developer-roadmap/issues/new) and incorporate them in the roadmap if suitable.
@ -53,40 +53,44 @@ Here is the full version of the roadmap in a single image and after that we have
[![](/roadmaps/android/roadmap.svg)](/roadmaps/android/roadmap.png) [![](/roadmaps/android/roadmap.svg)](/roadmaps/android/roadmap.png)
## Broken Down Version ## Broken Down Version
Below is the broken down version of the roadmap with links and resources to learn more about each of the items listed in the complete roadmap above. Below is the broken down version of the roadmap with links and resources to learn more about each of the items listed in the complete roadmap above.
## Pick a Language ## Pick a Language
For the languages, you can develop Android apps either by using Kotlin or Java. For the languages, you can develop Android apps either by using Kotlin or Java.
[![](/roadmaps/android/pick-language.svg)](/roadmaps/android/pick-language.svg) [![](/roadmaps/android/pick-language.svg)](/roadmaps/android/pick-language.svg)
Although, you can use both [Kotlin](https://en.wikipedia.org/wiki/Kotlin_(programming_language)) and [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) to develop native Android apps, [Google announced in 2019](https://android-developers.googleblog.com/2019/05/google-io-2019-empowering-developers-to-build-experiences-on-Android-Play.html) to make Kotlin the preferred way of developing Android applications. If you were to start learning Android development today, Kotlin should be your language of choice. Although, you can use both [Kotlin](<https://en.wikipedia.org/wiki/Kotlin_(programming_language)>) and [Java](<https://en.wikipedia.org/wiki/Java_(programming_language)>) to develop native Android apps, [Google announced in 2019](https://android-developers.googleblog.com/2019/05/google-io-2019-empowering-developers-to-build-experiences-on-Android-Play.html) to make Kotlin the preferred way of developing Android applications. If you were to start learning Android development today, Kotlin should be your language of choice.
## The Fundamentals ## The Fundamentals
Install [Android Studio](https://developer.android.com/studio) and learn the basics of Kotlin to get started. Install [Android Studio](https://developer.android.com/studio) and learn the basics of Kotlin to get started.
[![](/roadmaps/android/the-fundamentals.png)](/roadmaps/android/the-fundamentals.png) [![](/roadmaps/android/the-fundamentals.png)](/roadmaps/android/the-fundamentals.png)
We have also listed down some free resources which you can use for the items listed in the image above. If you have some better ones, please do suggest. Also, you don't need to go through all of them, just go through them and pick what you like. We have also listed down some free resources which you can use for the items listed in the image above. If you have some better ones, please do suggest. Also, you don't need to go through all of them, just go through them and pick what you like.
* [Learn the basics of Kotlin](https://blog.teamtreehouse.com/absolute-beginners-guide-kotlin) - [Learn the basics of Kotlin](https://blog.teamtreehouse.com/absolute-beginners-guide-kotlin)
* [Kotlin Docs](https://kotlinlang.org/docs/reference/basic-syntax.html) and [Official Kotlin Tutorials](https://kotlinlang.org/docs/tutorials/) - [Kotlin Docs](https://kotlinlang.org/docs/reference/basic-syntax.html) and [Official Kotlin Tutorials](https://kotlinlang.org/docs/tutorials/)
* [Data Structures and Algorithms](https://www.studytonight.com/data-structures/introduction-to-data-structures). Also [check this](https://www.tutorialspoint.com/data_structures_algorithms/index.htm). - [Data Structures and Algorithms](https://www.studytonight.com/data-structures/introduction-to-data-structures). Also [check this](https://www.tutorialspoint.com/data_structures_algorithms/index.htm).
* [Kotlin Data Structures](https://kotlinlang.org/docs/reference/collections-overview.html) - [Kotlin Data Structures](https://kotlinlang.org/docs/reference/collections-overview.html)
* [Algorithms and Data Structures in Kotlin](https://github.com/bmaslakov/kotlin-algorithm-club) - [Algorithms and Data Structures in Kotlin](https://github.com/bmaslakov/kotlin-algorithm-club)
* [Gradle](https://docs.gradle.org/current/userguide/what_is_gradle.html) - [Gradle](https://docs.gradle.org/current/userguide/what_is_gradle.html)
* [Getting started with Gradle](https://docs.gradle.org/current/userguide/getting_started.html) - [Getting started with Gradle](https://docs.gradle.org/current/userguide/getting_started.html)
Note: Android Studio comes with a working installation of Gradle, so you don’t need to install Gradle separately in that case. Note: Android Studio comes with a working installation of Gradle, so you don’t need to install Gradle separately in that case.
## Version Control Systems ## Version Control Systems
Version Control Systems record your changes to the codebase and allow you to recall specific versions later. There are multiple Version Control Systems available, but [Git](https://git-scm.com/) is the most common one these days. Version Control Systems record your changes to the codebase and allow you to recall specific versions later. There are multiple Version Control Systems available, but [Git](https://git-scm.com/) is the most common one these days.
[![](/roadmaps/android/git-github.png)](/roadmaps/android/git-github.png) [![](/roadmaps/android/git-github.png)](/roadmaps/android/git-github.png)
Here are some of the resources to get you started. Feel free to google and find something else that you find easier. Here are some of the resources to get you started. Feel free to google and find something else that you find easier.
* [Udacity — Version Control with Git](https://www.udacity.com/course/version-control-with-git--ud123) - [Udacity — Version Control with Git](https://www.udacity.com/course/version-control-with-git--ud123)
* [GitHub Hello World](https://guides.github.com/activities/hello-world/) - [GitHub Hello World](https://guides.github.com/activities/hello-world/)
## Building an Application ## Building an Application
@ -96,36 +100,39 @@ Here is the list of items that you are going to need when developing Android app
To learn more about the items listed in the image above, here are the links to the relevant docs. To learn more about the items listed in the image above, here are the links to the relevant docs.
* [Using Activities and Activity Life Cycles](https://developer.android.com/guide/components/activities/intro-activities) - [Using Activities and Activity Life Cycles](https://developer.android.com/guide/components/activities/intro-activities)
* Building Flexible Interfaces using [Fragments](https://developer.android.com/guide/components/fragments) - Building Flexible Interfaces using [Fragments](https://developer.android.com/guide/components/fragments)
* [Debugging using Android Studio Debugger](https://developer.android.com/studio/debug) - [Debugging using Android Studio Debugger](https://developer.android.com/studio/debug)
* [Handling App Configurations](https://developer.android.com/work/managed-configurations) - [Handling App Configurations](https://developer.android.com/work/managed-configurations)
* [Using Intents and Intent Filters](https://developer.android.com/guide/components/intents-filters) - [Using Intents and Intent Filters](https://developer.android.com/guide/components/intents-filters)
* [Understand Context](https://guides.codepath.com/android/Using-Context) - [Understand Context](https://guides.codepath.com/android/Using-Context)
* [Learn about Multithreading](https://developer.android.com/training/multiple-threads) - [Learn about Multithreading](https://developer.android.com/training/multiple-threads)
* [Data Privacy](https://www.raywenderlich.com/6901838-data-privacy-for-android) - [Data Privacy](https://www.raywenderlich.com/6901838-data-privacy-for-android)
* [Securing Network Data](https://www.raywenderlich.com/5634-securing-network-data-tutorial-for-android) - [Securing Network Data](https://www.raywenderlich.com/5634-securing-network-data-tutorial-for-android)
* [Dependency Injection](https://developer.android.com/training/dependency-injection) - [Dependency Injection](https://developer.android.com/training/dependency-injection)
* [Content Providers](https://developer.android.com/guide/topics/providers/content-providers) - [Content Providers](https://developer.android.com/guide/topics/providers/content-providers)
* [Glide](https://github.com/bumptech/glide), [Retrofit](https://square.github.io/retrofit/), [Crashlytics](https://firebase.google.com/docs/crashlytics/get-started), [GSON](https://github.com/google/gson) - [Glide](https://github.com/bumptech/glide), [Retrofit](https://square.github.io/retrofit/), [Crashlytics](https://firebase.google.com/docs/crashlytics/get-started), [GSON](https://github.com/google/gson)
* [Room](https://developer.android.com/topic/libraries/architecture/room), [Navigation](https://developer.android.com/guide/navigation/navigation-getting-started), [Work Manager](https://developer.android.com/topic/libraries/architecture/workmanager), [LiveData](https://developer.android.com/topic/libraries/architecture/livedata), [Data Binding](https://developer.android.com/topic/libraries/data-binding) - [Room](https://developer.android.com/topic/libraries/architecture/room), [Navigation](https://developer.android.com/guide/navigation/navigation-getting-started), [Work Manager](https://developer.android.com/topic/libraries/architecture/workmanager), [LiveData](https://developer.android.com/topic/libraries/architecture/livedata), [Data Binding](https://developer.android.com/topic/libraries/data-binding)
* [RxJava](https://github.com/ReactiveX/RxJava), [RxKotlin](https://github.com/ReactiveX/RxKotlin) - [RxJava](https://github.com/ReactiveX/RxJava), [RxKotlin](https://github.com/ReactiveX/RxKotlin)
* [Memory Management Overview](https://developer.android.com/topic/performance/memory-overview) - [Memory Management Overview](https://developer.android.com/topic/performance/memory-overview)
* [Diving deeper into context-oriented programming in Kotlin](https://proandroiddev.com/diving-deeper-into-context-oriented-programming-in-kotlin-3ecb4ec38814) - [Diving deeper into context-oriented programming in Kotlin](https://proandroiddev.com/diving-deeper-into-context-oriented-programming-in-kotlin-3ecb4ec38814)
## Jetpack Compose ## Jetpack Compose
Jetpack Compose is Android’s modern toolkit for building native UI. It simplifies and accelerates UI development on Android. Quickly bring your app to life with less code, powerful tools, and intuitive Kotlin APIs. Jetpack Compose is Android’s modern toolkit for building native UI. It simplifies and accelerates UI development on Android. Quickly bring your app to life with less code, powerful tools, and intuitive Kotlin APIs.
* [Jetpack Compose](https://developer.android.com/jetpack/compose/documentation)
* [Material Design 3](https://m3.material.io/) - [Jetpack Compose](https://developer.android.com/jetpack/compose/documentation)
* [Getting started with Material Components](https://m3.material.io/libraries/mdc-android/getting-started) - [Material Design 3](https://m3.material.io/)
- [Getting started with Material Components](https://m3.material.io/libraries/mdc-android/getting-started)
## Free Resources ## Free Resources
I would highly recommend watching [this free course](https://www.udacity.com/course/developing-android-apps-with-kotlin--ud9012) from Google on Developing Android Apps with Kotlin. You may also get started with this [free course](https://developer.android.com/courses/android-basics-kotlin/course) on the Android developer's page, where concepts are taught with the help of code labs, projects and quizzes, and you also earn badges as you learn that appear on your Google developer profile. Also, here are some of the resources to learn more about the topics listed above. I would highly recommend watching [this free course](https://www.udacity.com/course/developing-android-apps-with-kotlin--ud9012) from Google on Developing Android Apps with Kotlin. You may also get started with this [free course](https://developer.android.com/courses/android-basics-kotlin/course) on the Android developer's page, where concepts are taught with the help of code labs, projects and quizzes, and you also earn badges as you learn that appear on your Google developer profile. Also, here are some of the resources to learn more about the topics listed above.
* [Developing Android Apps with Kotlin](https://www.udacity.com/course/developing-android-apps-with-kotlin--ud9012) - [Developing Android Apps with Kotlin](https://www.udacity.com/course/developing-android-apps-with-kotlin--ud9012)
* [Android Basics in Kotlin](https://developer.android.com/courses/android-basics-kotlin/course) - [Android Basics in Kotlin](https://developer.android.com/courses/android-basics-kotlin/course)
* [Android Developer Guides](https://developer.android.com/guide) - [Android Developer Guides](https://developer.android.com/guide)
* [Kodeco](https://www.kodeco.com) - [Kodeco](https://www.kodeco.com)
## Wrap Up ## Wrap Up
@ -134,4 +141,5 @@ That wraps it up for the Android developer roadmap. Again, remember to not be ex
For any suggestions, improvements and feedback, feel free to [submit an issue](https://github.com/kamranahmedse/developer-roadmap) or reach out to me on twitter [@kamranahmedse](https://twitter.com/kamranahmedse). For any suggestions, improvements and feedback, feel free to [submit an issue](https://github.com/kamranahmedse/developer-roadmap) or reach out to me on twitter [@kamranahmedse](https://twitter.com/kamranahmedse).
<!-- @fixme add padding to the container --> <!-- @fixme add padding to the container -->
<br /><br /><br /> <br /><br /><br />

@ -1,48 +1,47 @@
--- ---
jsonUrl: "/jsons/roadmaps/angular.json" jsonUrl: '/jsons/roadmaps/angular.json'
pdfUrl: "/pdfs/roadmaps/angular.pdf" pdfUrl: '/pdfs/roadmaps/angular.pdf'
order: 3 order: 3
briefTitle: "Angular" briefTitle: 'Angular'
briefDescription: "Step by step guide to become a Angular Developer in 2023" briefDescription: 'Step by step guide to become a Angular Developer in 2023'
title: "Angular Developer" title: 'Angular Developer'
description: "Everything that is there to learn about Angular and the ecosystem in 2023." description: 'Everything that is there to learn about Angular and the ecosystem in 2023.'
hasTopics: true hasTopics: true
dimensions: dimensions:
width: 968 width: 968
height: 2277.8 height: 2277.8
schema: schema:
headline: "Angular Developer Roadmap" headline: 'Angular Developer Roadmap'
description: "Learn how to become a Angular Developer with this interactive step by step guide in 2023. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place." description: 'Learn how to become a Angular Developer with this interactive step by step guide in 2023. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place.'
imageUrl: "https://roadmap.sh/roadmaps/angular.png" imageUrl: 'https://roadmap.sh/roadmaps/angular.png'
datePublished: "2023-01-05" datePublished: '2023-01-05'
dateModified: "2023-01-20" dateModified: '2023-01-20'
seo: seo:
title: "Angular Developer Roadmap: Learn to become a Angular developer" title: 'Angular Developer Roadmap: Learn to become a Angular developer'
description: "Community driven, articles, resources, guides, interview questions, quizzes for angular development. Learn to become a modern Angular developer by following the steps, skills, resources and guides listed in this roadmap." description: 'Community driven, articles, resources, guides, interview questions, quizzes for angular development. Learn to become a modern Angular developer by following the steps, skills, resources and guides listed in this roadmap.'
keywords: keywords:
- "guide to becoming a angular developer" - 'guide to becoming a angular developer'
- "angular developer roadmap" - 'angular developer roadmap'
- "angular roadmap" - 'angular roadmap'
- "become angular developer" - 'become angular developer'
- "angular developer skills" - 'angular developer skills'
- "angular skills test" - 'angular skills test'
- "skills for angular development" - 'skills for angular development'
- "learn angular development" - 'learn angular development'
- "what is angular" - 'what is angular'
- "angular quiz" - 'angular quiz'
- "angular interview questions" - 'angular interview questions'
relatedRoadmaps: relatedRoadmaps:
- "frontend" - 'frontend'
- "javascript" - 'javascript'
- "react" - 'react'
- "vue" - 'vue'
- "nodejs" - 'nodejs'
sitemap: sitemap:
priority: 1 priority: 1
changefreq: "monthly" changefreq: 'monthly'
tags: tags:
- "roadmap" - 'roadmap'
- "main-sitemap" - 'main-sitemap'
- "skill-roadmap" - 'skill-roadmap'
--- ---

@ -9,4 +9,3 @@ Visit the following resources to learn more:
- [Structural typings — Medium](https://medium.com/redox-techblog/structural-typing-in-typescript-4b89f21d6004) - [Structural typings — Medium](https://medium.com/redox-techblog/structural-typing-in-typescript-4b89f21d6004)
- [Structural typings — Typescriptlang](https://www.typescriptlang.org/docs/handbook/type-compatibility.html) - [Structural typings — Typescriptlang](https://www.typescriptlang.org/docs/handbook/type-compatibility.html)
- [Structural typing video for Beginners](https://www.youtube.com/watch?v=kWtwsX_rT3k) - [Structural typing video for Beginners](https://www.youtube.com/watch?v=kWtwsX_rT3k)

@ -3,6 +3,7 @@
An observable is a function that acts as a wrapper for a data stream. They support to pass messages inside your application. An observable is useless until an observer subscribes to it. An observer is an object which consumes the data emitted by the observable. An observer keeps receiving data values from the observable until the observable is completed, or the observer unsubscribes from the observable. Otherwise observers can receive data values from the observable continuously and asynchronously. So we can perform various operations such as updating the user interface, or passing the JSON response. An observable is a function that acts as a wrapper for a data stream. They support to pass messages inside your application. An observable is useless until an observer subscribes to it. An observer is an object which consumes the data emitted by the observable. An observer keeps receiving data values from the observable until the observable is completed, or the observer unsubscribes from the observable. Otherwise observers can receive data values from the observable continuously and asynchronously. So we can perform various operations such as updating the user interface, or passing the JSON response.
There are 4 stages for a life cycle of an observable. There are 4 stages for a life cycle of an observable.
- Creation - Creation
- Subscription - Subscription
- Execution - Execution

@ -1,6 +1,5 @@
# RxJS Operators # RxJS Operators
RxJS is mostly useful for its operators, even though the Observable is the foundation. Operators are the essential pieces that allow complex asynchronous code to be easily composed in a declarative manner. RxJS is mostly useful for its operators, even though the Observable is the foundation. Operators are the essential pieces that allow complex asynchronous code to be easily composed in a declarative manner.
Operators are functions. There are two kinds of operators: Operators are functions. There are two kinds of operators:
@ -35,4 +34,3 @@ Visit the following resources to learn more:
- [List of creation operators](https://rxjs.dev/guide/operators#creation-operators-list) - [List of creation operators](https://rxjs.dev/guide/operators#creation-operators-list)
- [Full RxJS Operators Documentation](https://rxjs.dev/guide/operators) - [Full RxJS Operators Documentation](https://rxjs.dev/guide/operators)

@ -2,10 +2,10 @@
Components are the main building block for Angular applications. Each component consists of: Components are the main building block for Angular applications. Each component consists of:
* An HTML template that declares what renders on the page - An HTML template that declares what renders on the page
* A TypeScript class that defines the behavior - A TypeScript class that defines the behavior
* A CSS selector that defines how the component is used in a template - A CSS selector that defines how the component is used in a template
* Optionally, CSS styles applied to the template - Optionally, CSS styles applied to the template
Visit the following resources to learn more: Visit the following resources to learn more:

@ -2,7 +2,6 @@
ng generate is used to create the component in angular project. These are the two main ways to generate a new component in Angular: using ng g c <component_name>, and using ng generate component <component_name>. Using either of these two commands, the new component can be generated pretty easily and followed by the suitable component name of your choice. ng generate is used to create the component in angular project. These are the two main ways to generate a new component in Angular: using ng g c <component_name>, and using ng generate component <component_name>. Using either of these two commands, the new component can be generated pretty easily and followed by the suitable component name of your choice.
Visit the following resources to learn more: Visit the following resources to learn more:
- [Ng generate - Angular.io](https://angular.io/cli/generate) - [Ng generate - Angular.io](https://angular.io/cli/generate)

@ -4,7 +4,6 @@ ng test is used to runs unit tests in angular project.
`ng test <project> [options]` | `ng t <project> [options]` `ng test <project> [options]` | `ng t <project> [options]`
Visit the following resources to learn more: Visit the following resources to learn more:
- [Ng test - Angular.io](https://angular.io/cli/test) - [Ng test - Angular.io](https://angular.io/cli/test)

@ -4,7 +4,6 @@ SKDirectives are classes that add additional behavior to elements in your Angula
`NgClass` Adds and removes a set of CSS classes. | `NgStyle` Adds and removes a set of HTML styles. | `NgModel` Adds two-way data binding to an HTML form element. `NgClass` Adds and removes a set of CSS classes. | `NgStyle` Adds and removes a set of HTML styles. | `NgModel` Adds two-way data binding to an HTML form element.
Visit the following resources to learn more: Visit the following resources to learn more:
- [Understanding BuiltIn Directives](https://angular.io/guide/built-in-directives) - [Understanding BuiltIn Directives](https://angular.io/guide/built-in-directives)

@ -4,7 +4,6 @@ Use pipes to transform strings, currency amounts, dates, and other data for disp
`DatePipe` | `UpperCasePipe` | `LowerCasePipe` | `CurrencyPipe` | `DecimalPipe` | `PercentPipe` `DatePipe` | `UpperCasePipe` | `LowerCasePipe` | `CurrencyPipe` | `DecimalPipe` | `PercentPipe`
Visit the following resources to learn more: Visit the following resources to learn more:
- [Understanding BuiltIn Pipes](https://angular.io/guide/pipes) - [Understanding BuiltIn Pipes](https://angular.io/guide/pipes)

@ -6,4 +6,3 @@ Visit the following resources to learn more:
- [What is Dependency Injection ? - angular.io ](https://angular.io/guide/dependency-injection) - [What is Dependency Injection ? - angular.io ](https://angular.io/guide/dependency-injection)
- [Introduction of Dependency injection](https://www.youtube.com/watch?v=OFPIGlxunL0) - [Introduction of Dependency injection](https://www.youtube.com/watch?v=OFPIGlxunL0)

@ -7,4 +7,3 @@ Visit the following resources to learn more:
- [What is NGXS ? - Ngxs.io ](https://www.ngxs.io/) - [What is NGXS ? - Ngxs.io ](https://www.ngxs.io/)
- [Details about NGXS - Medium ](https://medium.com/@knoldus/introduction-to-ngxs-state-management-pattern-library-for-angular-ec76f681ceba) - [Details about NGXS - Medium ](https://medium.com/@knoldus/introduction-to-ngxs-state-management-pattern-library-for-angular-ec76f681ceba)
- [Practise of NGXS](https://www.youtube.com/watch?v=SGj11j4hxmg) - [Practise of NGXS](https://www.youtube.com/watch?v=SGj11j4hxmg)

@ -6,4 +6,3 @@ Visit the following resources to learn more:
- [What is NGRX ? - ngrx.io ](https://ngrx.io/) - [What is NGRX ? - ngrx.io ](https://ngrx.io/)
- [Details about NGRX - Medium ](https://ahmedrebai.medium.com/introduction-to-state-management-with-ngrx-and-angular-91f4ff27ec9f) - [Details about NGRX - Medium ](https://ahmedrebai.medium.com/introduction-to-state-management-with-ngrx-and-angular-91f4ff27ec9f)
- [Practise of NGRX](https://www.youtube.com/watch?v=f97ICOaekNU) - [Practise of NGRX](https://www.youtube.com/watch?v=f97ICOaekNU)

@ -1,62 +1,61 @@
--- ---
jsonUrl: "/jsons/roadmaps/aspnet-core.json" jsonUrl: '/jsons/roadmaps/aspnet-core.json'
pdfUrl: "/pdfs/roadmaps/aspnet-core.pdf" pdfUrl: '/pdfs/roadmaps/aspnet-core.pdf'
order: 9 order: 9
briefTitle: "ASP.NET Core" briefTitle: 'ASP.NET Core'
briefDescription: "Step by step guide to becoming an ASP.NET Core Developer in 2023" briefDescription: 'Step by step guide to becoming an ASP.NET Core Developer in 2023'
title: "ASP.NET Core Developer" title: 'ASP.NET Core Developer'
description: "Step by step guide to becoming an ASP.NET core developer in 2023" description: 'Step by step guide to becoming an ASP.NET core developer in 2023'
isNew: false isNew: false
hasTopics: true hasTopics: true
dimensions: dimensions:
width: 968 width: 968
height: 2773.45 height: 2773.45
schema: schema:
headline: "ASP.NET Core Developer Roadmap" headline: 'ASP.NET Core Developer Roadmap'
description: "Learn how to become a ASP.NET Core Developer with this interactive step by step guide in 2023. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place." description: 'Learn how to become a ASP.NET Core Developer with this interactive step by step guide in 2023. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place.'
imageUrl: "https://roadmap.sh/roadmaps/aspnet-core.png" imageUrl: 'https://roadmap.sh/roadmaps/aspnet-core.png'
datePublished: "2023-01-05" datePublished: '2023-01-05'
dateModified: "2023-01-20" dateModified: '2023-01-20'
seo: seo:
title: "Learn to become a modern ASP.NET core developer" title: 'Learn to become a modern ASP.NET core developer'
description: "Community driven, articles, resources, guides, interview questions, quizzes for asp.net core development. Learn to become a modern ASP.NET core developer by following the steps, skills, resources and guides listed in this roadmap." description: 'Community driven, articles, resources, guides, interview questions, quizzes for asp.net core development. Learn to become a modern ASP.NET core developer by following the steps, skills, resources and guides listed in this roadmap.'
keywords: keywords:
- "guide to becoming a developer" - 'guide to becoming a developer'
- "guide to becoming an asp.net core developer" - 'guide to becoming an asp.net core developer'
- "asp.net core developer" - 'asp.net core developer'
- "asp.net core engineer" - 'asp.net core engineer'
- "asp.net core skills" - 'asp.net core skills'
- "guide to asp.net core" - 'guide to asp.net core'
- "asp.net developer roadmap" - 'asp.net developer roadmap'
- "asp net developer roadmap" - 'asp net developer roadmap'
- "asp developer roadmap" - 'asp developer roadmap'
- "asp.net core roadmap" - 'asp.net core roadmap'
- "asp.net core skills" - 'asp.net core skills'
- "asp.net core skills test" - 'asp.net core skills test'
- "skills for asp.net core" - 'skills for asp.net core'
- "cloud development" - 'cloud development'
- "what is asp.net core" - 'what is asp.net core'
- "asp.net core quiz" - 'asp.net core quiz'
- "asp.net core interview questions" - 'asp.net core interview questions'
- "asp.net core engineer roadmap" - 'asp.net core engineer roadmap'
- "asp.net core developer roadmap" - 'asp.net core developer roadmap'
- "become an asp.net core developer" - 'become an asp.net core developer'
- "asp.net core developer career path" - 'asp.net core developer career path'
- "asp.net core developer" - 'asp.net core developer'
- "modern asp.net core developer" - 'modern asp.net core developer'
relatedRoadmaps: relatedRoadmaps:
- "backend" - 'backend'
- "devops" - 'devops'
- "python" - 'python'
- "golang" - 'golang'
- "java" - 'java'
- "nodejs" - 'nodejs'
sitemap: sitemap:
priority: 1 priority: 1
changefreq: "monthly" changefreq: 'monthly'
tags: tags:
- "roadmap" - 'roadmap'
- "main-sitemap" - 'main-sitemap'
- "role-roadmap" - 'role-roadmap'
--- ---

@ -7,7 +7,6 @@ Although SQL is an ANSI/ISO standard, there are different versions of the SQL la
However, to be compliant with the ANSI standard, they all support at least the major commands (such as SELECT, UPDATE, DELETE, INSERT, WHERE) in a similar manner. However, to be compliant with the ANSI standard, they all support at least the major commands (such as SELECT, UPDATE, DELETE, INSERT, WHERE) in a similar manner.
Visit the following resources to learn more: Visit the following resources to learn more:
- [Introduction to SQL](https://www.w3schools.com/sql/sql_intro.asp) - [Introduction to SQL](https://www.w3schools.com/sql/sql_intro.asp)

@ -1,7 +1,5 @@
# CosmosDB # CosmosDB
For more information, visit the following resources: For more information, visit the following resources:
- [What is Azure Cosmos DB?](https://intellipaat.com/blog/what-is-azure-cosmos-db/) - [What is Azure Cosmos DB?](https://intellipaat.com/blog/what-is-azure-cosmos-db/)

@ -4,7 +4,6 @@ CouchDB is an open-source, NoSQL document database designed for the web. It uses
In an ASP.NET application, CouchDB can be used as a data store to persist and retrieve application data. There are several libraries available for integrating CouchDB with an ASP.NET application, such as Couchbase, which provides a .NET client for CouchDB that can be used to interact with the CouchDB server from within an ASP.NET application. In an ASP.NET application, CouchDB can be used as a data store to persist and retrieve application data. There are several libraries available for integrating CouchDB with an ASP.NET application, such as Couchbase, which provides a .NET client for CouchDB that can be used to interact with the CouchDB server from within an ASP.NET application.
Visit the following resources to learn more: Visit the following resources to learn more:
- [CouchDB in ASP.NET Core Application](https://www.c-sharpcorner.com/article/crud-operation-to-couchdb-via-rest-api-in-asp-net-core-application/) - [CouchDB in ASP.NET Core Application](https://www.c-sharpcorner.com/article/crud-operation-to-couchdb-via-rest-api-in-asp-net-core-application/)

@ -10,7 +10,6 @@ In an ASP.NET application, there are several types of databases that can be used
Each database type has its own set of features and use cases, and the choice of which database to use will depend on the specific requirements of the application. Each database type has its own set of features and use cases, and the choice of which database to use will depend on the specific requirements of the application.
To learn more, visit the following links: To learn more, visit the following links:
- [ASP.NET Database Tutorial](https://www.guru99.com/insert-update-delete-asp-net.html) - [ASP.NET Database Tutorial](https://www.guru99.com/insert-update-delete-asp-net.html)

@ -4,7 +4,6 @@ TeamCity is a Java-based continuous integration and continuous delivery (CI/CD)
In ASP.NET, TeamCity can be used to automate various tasks related to the development, testing, and deployment of ASP.NET applications. For example, you can use TeamCity to automatically build, test, and deploy an ASP.NET application to a hosting provider, such as Azure or AWS, every time you push code to your source control repository. In ASP.NET, TeamCity can be used to automate various tasks related to the development, testing, and deployment of ASP.NET applications. For example, you can use TeamCity to automatically build, test, and deploy an ASP.NET application to a hosting provider, such as Azure or AWS, every time you push code to your source control repository.
Visit the following links to learn more: Visit the following links to learn more:
- [Tutorial on TeamCity with ASP.NET](https://www.jetbrains.com/help/teamcity/net.html) - [Tutorial on TeamCity with ASP.NET](https://www.jetbrains.com/help/teamcity/net.html)

@ -3,6 +3,7 @@
Blazor is a framework for building web applications using C# and .NET that runs in the browser via WebAssembly. It allows developers to write C# code that runs directly in the browser, eliminating the need for JavaScript. Blazor is a framework for building web applications using C# and .NET that runs in the browser via WebAssembly. It allows developers to write C# code that runs directly in the browser, eliminating the need for JavaScript.
Blazor comes in two flavors: Blazor comes in two flavors:
- Blazor WebAssembly, a client-side solution that allows you to run C# code directly in the browser using WebAssembly. The app is executed on the client-side and can work offline, it can also interact with JavaScript and access the browser's DOM. - Blazor WebAssembly, a client-side solution that allows you to run C# code directly in the browser using WebAssembly. The app is executed on the client-side and can work offline, it can also interact with JavaScript and access the browser's DOM.
- Blazor Server, a server-side solution that allows you to run C# code on the server and update the UI in real-time. The app is executed on the server-side and requires an active connection to the server to function. - Blazor Server, a server-side solution that allows you to run C# code on the server and update the UI in real-time. The app is executed on the server-side and requires an active connection to the server to function.

@ -1,74 +1,73 @@
--- ---
jsonUrl: "/jsons/roadmaps/backend.json" jsonUrl: '/jsons/roadmaps/backend.json'
pdfUrl: "/pdfs/roadmaps/backend.pdf" pdfUrl: '/pdfs/roadmaps/backend.pdf'
order: 2 order: 2
briefTitle: "Backend" briefTitle: 'Backend'
briefDescription: "Step by step guide to becoming a backend developer in 2023" briefDescription: 'Step by step guide to becoming a backend developer in 2023'
title: "Backend Developer" title: 'Backend Developer'
description: "Step by step guide to becoming a modern backend developer in 2023" description: 'Step by step guide to becoming a modern backend developer in 2023'
hasTopics: true hasTopics: true
tnsBannerLink: "https://thenewstack.io?utm_source=roadmap.sh&utm_medium=Referral&utm_campaign=Alert" tnsBannerLink: 'https://thenewstack.io?utm_source=roadmap.sh&utm_medium=Referral&utm_campaign=Alert'
dimensions: dimensions:
width: 968 width: 968
height: 2840.4 height: 2840.4
sponsor: sponsor:
url: "https://www.fermyon.com/spin?utm_source=backend&utm_medium=banner&utm_campaign=roadmap-sh" url: 'https://www.fermyon.com/spin?utm_source=backend&utm_medium=banner&utm_campaign=roadmap-sh'
title: "Serverless Backend Apps" title: 'Serverless Backend Apps'
imageUrl: "https://i.imgur.com/2ONZopb.jpg" imageUrl: 'https://i.imgur.com/2ONZopb.jpg'
description: "Go from blinking cursor to deployed serverless Backend apps in 66 seconds with Fermyon Cloud." description: 'Go from blinking cursor to deployed serverless Backend apps in 66 seconds with Fermyon Cloud.'
event: event:
category: "SponsorClick" category: 'SponsorClick'
action: "Fermyon Redirect" action: 'Fermyon Redirect'
label: "Backend / Fermyon Link" label: 'Backend / Fermyon Link'
schema: schema:
headline: "Backend Developer Roadmap" headline: 'Backend Developer Roadmap'
description: "Learn how to become a Backend Developer with this interactive step by step guide in 2023. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place." description: 'Learn how to become a Backend Developer with this interactive step by step guide in 2023. We also have resources and short descriptions attached to the roadmap items so you can get everything you want to learn in one place.'
imageUrl: "https://roadmap.sh/roadmaps/backend.png" imageUrl: 'https://roadmap.sh/roadmaps/backend.png'
datePublished: "2023-01-05" datePublished: '2023-01-05'
dateModified: "2023-01-20" dateModified: '2023-01-20'
seo: seo:
title: "Backend Developer Roadmap" title: 'Backend Developer Roadmap'
description: "Learn to become a modern backend developer using this roadmap. Community driven, articles, resources, guides, interview questions, quizzes for modern backend development." description: 'Learn to become a modern backend developer using this roadmap. Community driven, articles, resources, guides, interview questions, quizzes for modern backend development.'
keywords: keywords:
- "backend roadmap 2023" - 'backend roadmap 2023'
- "backend developer roadmap 2023" - 'backend developer roadmap 2023'
- "guide to becoming a developer" - 'guide to becoming a developer'
- "guide to becoming a backend developer" - 'guide to becoming a backend developer'
- "backend roadmap" - 'backend roadmap'
- "backend developer" - 'backend developer'
- "backend engineer" - 'backend engineer'
- "backend skills" - 'backend skills'
- "backend development" - 'backend development'
- "javascript developer" - 'javascript developer'
- "backend development skills" - 'backend development skills'
- "backend development skills test" - 'backend development skills test'
- "backend engineer roadmap" - 'backend engineer roadmap'
- "backend developer roadmap" - 'backend developer roadmap'
- "become a backend developer" - 'become a backend developer'
- "backend developer career path" - 'backend developer career path'
- "javascript developer" - 'javascript developer'
- "modern javascript developer" - 'modern javascript developer'
- "node developer" - 'node developer'
- "skills for backend development" - 'skills for backend development'
- "learn backend development" - 'learn backend development'
- "what is backend development" - 'what is backend development'
- "backend developer quiz" - 'backend developer quiz'
- "backend developer interview questions" - 'backend developer interview questions'
relatedRoadmaps: relatedRoadmaps:
- "system-design" - 'system-design'
- "python" - 'python'
- "java" - 'java'
- "golang" - 'golang'
- "devops" - 'devops'
- "javascript" - 'javascript'
- "nodejs" - 'nodejs'
- "postgresql-dba" - 'postgresql-dba'
sitemap: sitemap:
priority: 1 priority: 1
changefreq: "monthly" changefreq: 'monthly'
tags: tags:
- "roadmap" - 'roadmap'
- "main-sitemap" - 'main-sitemap'
- "role-roadmap" - 'role-roadmap'
--- ---

@ -4,7 +4,6 @@ HTTP is the `TCP/IP` based application layer communication protocol which standa
Visit the following resources to learn more: Visit the following resources to learn more:
- [Everything you need to know about HTTP](https://cs.fyi/guide/http-in-depth) - [Everything you need to know about HTTP](https://cs.fyi/guide/http-in-depth)
- [What is HTTP?](https://www.cloudflare.com/en-gb/learning/ddos/glossary/hypertext-transfer-protocol-http/) - [What is HTTP?](https://www.cloudflare.com/en-gb/learning/ddos/glossary/hypertext-transfer-protocol-http/)
- [Full HTTP Networking Course](https://www.youtube.com/watch?v=2JYT5f2isg4) - [Full HTTP Networking Course](https://www.youtube.com/watch?v=2JYT5f2isg4)

@ -13,4 +13,3 @@ Visit the following resources to learn more:
- [CSS Crash Course For Absolute Beginners](https://www.youtube.com/watch?v=yfoY53QXEnI) - [CSS Crash Course For Absolute Beginners](https://www.youtube.com/watch?v=yfoY53QXEnI)
- [HTML and CSS Tutorial](https://www.youtube.com/watch?v=D-h8L5hgW-w) - [HTML and CSS Tutorial](https://www.youtube.com/watch?v=D-h8L5hgW-w)
- [CSS Masterclass - Tutorial & Course for Beginners](https://www.youtube.com/watch?v=FqmB-Zj2-PA) - [CSS Masterclass - Tutorial & Course for Beginners](https://www.youtube.com/watch?v=FqmB-Zj2-PA)

@ -2,7 +2,7 @@
POSIX (Portable Operating System Interface) is a family of standards for maintaining compatibility between operating systems. It describes utilities, APIs, and services that a compliant OS should provide to software, thus making it easier to port programs from one system to another. POSIX (Portable Operating System Interface) is a family of standards for maintaining compatibility between operating systems. It describes utilities, APIs, and services that a compliant OS should provide to software, thus making it easier to port programs from one system to another.
A practical example: in a Unix-like operating system, there are three *standard streams*, `stdin`, `stdout` and `stderr` - they are I/O connections that you will probably come across when using a terminal, as they manage the flow from the **standard input** (stdin), **standard output** (stdout) and **standard error** (stderr). A practical example: in a Unix-like operating system, there are three _standard streams_, `stdin`, `stdout` and `stderr` - they are I/O connections that you will probably come across when using a terminal, as they manage the flow from the **standard input** (stdin), **standard output** (stdout) and **standard error** (stderr).
So, in this case, when we want to interact with any of these streams (through a process, for example), the POSIX operating system API makes it easier - for example, in the `<unistd.h>` C header where the stdin, stderr, and stdout are defined as `STDIN_FILENO`, `STDERR_FILENO` and `STDOUT_FILENO`. So, in this case, when we want to interact with any of these streams (through a process, for example), the POSIX operating system API makes it easier - for example, in the `<unistd.h>` C header where the stdin, stderr, and stdout are defined as `STDIN_FILENO`, `STDERR_FILENO` and `STDOUT_FILENO`.

@ -1,4 +1,5 @@
# C# # C#
C# (pronounced "C sharp") is a general purpose programming language made by Microsoft. It is used to perform different tasks and can be used to create web apps, games, mobile apps, etc. C# (pronounced "C sharp") is a general purpose programming language made by Microsoft. It is used to perform different tasks and can be used to create web apps, games, mobile apps, etc.
Visit the following resources to learn more: Visit the following resources to learn more:

@ -2,7 +2,6 @@
Version control/source control systems allow developers to track and control changes to code over time. These services often include the ability to make atomic revisions to code, branch/fork off of specific points, and to compare versions of code. They are useful in determining the who, what, when, and why code changes were made. Version control/source control systems allow developers to track and control changes to code over time. These services often include the ability to make atomic revisions to code, branch/fork off of specific points, and to compare versions of code. They are useful in determining the who, what, when, and why code changes were made.
Visit the following resources to learn more: Visit the following resources to learn more:
- [Git](https://git-scm.com/) - [Git](https://git-scm.com/)

@ -2,13 +2,13 @@
There are several different failure modes that can occur in a database, including: There are several different failure modes that can occur in a database, including:
* Read contention: This occurs when multiple clients or processes are trying to read data from the same location in the database at the same time, which can lead to delays or errors. - Read contention: This occurs when multiple clients or processes are trying to read data from the same location in the database at the same time, which can lead to delays or errors.
* Write contention: This occurs when multiple clients or processes are trying to write data to the same location in the database at the same time, which can lead to delays or errors. - Write contention: This occurs when multiple clients or processes are trying to write data to the same location in the database at the same time, which can lead to delays or errors.
* Thundering herd: This occurs when a large number of clients or processes try to access the same resource simultaneously, which can lead to resource exhaustion and reduced performance. - Thundering herd: This occurs when a large number of clients or processes try to access the same resource simultaneously, which can lead to resource exhaustion and reduced performance.
* Cascade: This occurs when a failure in one part of the database system causes a chain reaction that leads to failures in other parts of the system. - Cascade: This occurs when a failure in one part of the database system causes a chain reaction that leads to failures in other parts of the system.
* Deadlock: This occurs when two or more transactions are waiting for each other to release a lock on a resource, leading to a standstill. - Deadlock: This occurs when two or more transactions are waiting for each other to release a lock on a resource, leading to a standstill.
* Corruption: This occurs when data in the database becomes corrupted, which can lead to errors or unexpected results when reading or writing to the database. - Corruption: This occurs when data in the database becomes corrupted, which can lead to errors or unexpected results when reading or writing to the database.
* Hardware failure: This occurs when hardware components, such as disk drives or memory, fail, which can lead to data loss or corruption. - Hardware failure: This occurs when hardware components, such as disk drives or memory, fail, which can lead to data loss or corruption.
* Software failure: This occurs when software components, such as the database management system or application, fail, which can lead to errors or unexpected results. - Software failure: This occurs when software components, such as the database management system or application, fail, which can lead to errors or unexpected results.
* Network failure: This occurs when the network connection between the database and the client is lost, which can lead to errors or timeouts when trying to access the database. - Network failure: This occurs when the network connection between the database and the client is lost, which can lead to errors or timeouts when trying to access the database.
* Denial of service (DoS) attack: This occurs when a malicious actor attempts to overwhelm the database with requests, leading to resource exhaustion and reduced performance. - Denial of service (DoS) attack: This occurs when a malicious actor attempts to overwhelm the database with requests, leading to resource exhaustion and reduced performance.

@ -2,10 +2,10 @@
There are several ways to profile the performance of a database: There are several ways to profile the performance of a database:
* Monitor system performance: You can use tools like the Windows Task Manager or the Unix/Linux top command to monitor the performance of your database server. These tools allow you to see the overall CPU, memory, and disk usage of the system, which can help identify any resource bottlenecks. - Monitor system performance: You can use tools like the Windows Task Manager or the Unix/Linux top command to monitor the performance of your database server. These tools allow you to see the overall CPU, memory, and disk usage of the system, which can help identify any resource bottlenecks.
* Use database-specific tools: Most database management systems (DBMSs) have their own tools for monitoring performance. For example, Microsoft SQL Server has the SQL Server Management Studio (SSMS) and the sys.dm_os_wait_stats dynamic management view, while Oracle has the Oracle Enterprise Manager and the v$waitstat view. These tools allow you to see specific performance metrics, such as the amount of time spent waiting on locks or the number of physical reads and writes. - Use database-specific tools: Most database management systems (DBMSs) have their own tools for monitoring performance. For example, Microsoft SQL Server has the SQL Server Management Studio (SSMS) and the sys.dm_os_wait_stats dynamic management view, while Oracle has the Oracle Enterprise Manager and the v$waitstat view. These tools allow you to see specific performance metrics, such as the amount of time spent waiting on locks or the number of physical reads and writes.
* Use third-party tools: There are also several third-party tools that can help you profile the performance of a database. Some examples include SolarWinds Database Performance Analyzer, Quest Software Foglight, and Redgate SQL Monitor. These tools often provide more in-depth performance analysis and can help you identify specific issues or bottlenecks. - Use third-party tools: There are also several third-party tools that can help you profile the performance of a database. Some examples include SolarWinds Database Performance Analyzer, Quest Software Foglight, and Redgate SQL Monitor. These tools often provide more in-depth performance analysis and can help you identify specific issues or bottlenecks.
* Analyze slow queries: If you have specific queries that are running slowly, you can use tools like EXPLAIN PLAN or SHOW PLAN in MySQL or SQL Server to see the execution plan for the query and identify any potential issues. You can also use tools like the MySQL slow query log or the SQL Server Profiler to capture slow queries and analyze them further. - Analyze slow queries: If you have specific queries that are running slowly, you can use tools like EXPLAIN PLAN or SHOW PLAN in MySQL or SQL Server to see the execution plan for the query and identify any potential issues. You can also use tools like the MySQL slow query log or the SQL Server Profiler to capture slow queries and analyze them further.
* Monitor application performance: If you are experiencing performance issues with a specific application that is using the database, you can use tools like Application Insights or New Relic to monitor the performance of the application and identify any issues that may be related to the database. - Monitor application performance: If you are experiencing performance issues with a specific application that is using the database, you can use tools like Application Insights or New Relic to monitor the performance of the application and identify any issues that may be related to the database.
Have a look at the documentation for the database that you are using. Have a look at the documentation for the database that you are using.

@ -5,4 +5,3 @@ Cookies are pieces of data used to identify the user and their preferences. The
Visit the following resources to learn more: Visit the following resources to learn more:
- [How does cookie based authentication work?](https://stackoverflow.com/questions/17769011/how-does-cookie-based-authentication-work) - [How does cookie based authentication work?](https://stackoverflow.com/questions/17769011/how-does-cookie-based-authentication-work)

@ -8,7 +8,6 @@ Token-based authentication is different from traditional password-based or serve
But using tokens requires a bit of coding know-how. Most developers pick up the techniques quickly, but there is a learning curve. But using tokens requires a bit of coding know-how. Most developers pick up the techniques quickly, but there is a learning curve.
Visit the following resources to learn more: Visit the following resources to learn more:
- [What Is Token-Based Authentication?](https://www.okta.com/identity-101/what-is-token-based-authentication/) - [What Is Token-Based Authentication?](https://www.okta.com/identity-101/what-is-token-based-authentication/)

@ -5,5 +5,5 @@ Sharding strategy is a technique to split a large dataset into smaller chunks (l
Visit the following resources to learn more: Visit the following resources to learn more:
- [Database Sharding – System Design Interview Concept](https://www.geeksforgeeks.org/database-sharding-a-system-design-concept/) - [Database Sharding – System Design Interview Concept](https://www.geeksforgeeks.org/database-sharding-a-system-design-concept/)
- [Wikipedia - Sharding in Datbase Architectures](https://en.wikipedia.org/wiki/Shard_(database_architecture)) - [Wikipedia - Sharding in Datbase Architectures](<https://en.wikipedia.org/wiki/Shard_(database_architecture)>)
- [How sharding a database can make it faster](https://stackoverflow.blog/2022/03/14/how-sharding-a-database-can-make-it-faster/) - [How sharding a database can make it faster](https://stackoverflow.blog/2022/03/14/how-sharding-a-database-can-make-it-faster/)

@ -4,7 +4,6 @@ A Content Delivery Network (CDN) service aims to provide high availability and p
Traditional commercial CDNs (Amazon CloudFront, Akamai, CloudFlare and Fastly) provide servers across the globe which can be used for this purpose. Traditional commercial CDNs (Amazon CloudFront, Akamai, CloudFlare and Fastly) provide servers across the globe which can be used for this purpose.
Serving assets and contents via a CDN reduces bandwidth on website hosting, provides an extra layer of caching to reduce potential outages and can improve website security as well Serving assets and contents via a CDN reduces bandwidth on website hosting, provides an extra layer of caching to reduce potential outages and can improve website security as well
Visit the following resources to learn more: Visit the following resources to learn more:
- [CloudFlare - What is a CDN? | How do CDNs work?](https://www.cloudflare.com/en-ca/learning/cdn/what-is-a-cdn/) - [CloudFlare - What is a CDN? | How do CDNs work?](https://www.cloudflare.com/en-ca/learning/cdn/what-is-a-cdn/)

@ -10,4 +10,3 @@ Visit the following resources to learn more:
- [Server-side caching ](https://www.starwindsoftware.com/resource-library/server-side-caching/) - [Server-side caching ](https://www.starwindsoftware.com/resource-library/server-side-caching/)
- [Server-side caching and Client-side caching](https://www.codingninjas.com/codestudio/library/server-side-caching-and-client-side-caching) - [Server-side caching and Client-side caching](https://www.codingninjas.com/codestudio/library/server-side-caching-and-client-side-caching)

@ -1,6 +1,7 @@
# SHA family # SHA family
SHA (Secure Hash Algorithms) is a family of cryptographic hash functions created by the NIST (National Institute of Standards and Technology). The family includes: SHA (Secure Hash Algorithms) is a family of cryptographic hash functions created by the NIST (National Institute of Standards and Technology). The family includes:
- SHA-0: Published in 1993, this is the first algorithm in the family. Shortly after its release, it was discontinued for an undisclosed significant flaw. - SHA-0: Published in 1993, this is the first algorithm in the family. Shortly after its release, it was discontinued for an undisclosed significant flaw.
- SHA-1: Created to replace SHA-0 and which resembles MD5, this algorithm has been considered insecure since 2010. - SHA-1: Created to replace SHA-0 and which resembles MD5, this algorithm has been considered insecure since 2010.
- SHA-2: This isn't an algorithm, but a set of them, with SHA-256 and SHA-512 being the most popular. SHA-2 is still secure and widely used. - SHA-2: This isn't an algorithm, but a set of them, with SHA-256 and SHA-512 being the most popular. SHA-2 is still secure and widely used.

@ -2,12 +2,12 @@
Learn about the security of your server and how to secure it. Here are some of the topics off the top of my head: Learn about the security of your server and how to secure it. Here are some of the topics off the top of my head:
* Use a firewall: One of the most effective ways to secure a server is to use a firewall to block all unnecessary incoming traffic. You can use iptables on Linux systems or a hardware firewall to do this. - Use a firewall: One of the most effective ways to secure a server is to use a firewall to block all unnecessary incoming traffic. You can use iptables on Linux systems or a hardware firewall to do this.
* Close unnecessary ports: Make sure to close any ports that are not needed for your server to function properly. This will reduce the attack surface of your server and make it more difficult for attackers to gain access. - Close unnecessary ports: Make sure to close any ports that are not needed for your server to function properly. This will reduce the attack surface of your server and make it more difficult for attackers to gain access.
* Use strong passwords: Use long, complex passwords for all of your accounts, and consider using a password manager to store them securely. - Use strong passwords: Use long, complex passwords for all of your accounts, and consider using a password manager to store them securely.
* Keep your system up to date: Make sure to keep your operating system and software up to date with the latest security patches. This will help to prevent vulnerabilities from being exploited by attackers. - Keep your system up to date: Make sure to keep your operating system and software up to date with the latest security patches. This will help to prevent vulnerabilities from being exploited by attackers.
* Use SSL/TLS for communication: Use Secure Sockets Layer (SSL) or Transport Layer Security (TLS) to encrypt communication between your server and client devices. This will help to protect against man-in-the-middle attacks and other types of cyber threats. - Use SSL/TLS for communication: Use Secure Sockets Layer (SSL) or Transport Layer Security (TLS) to encrypt communication between your server and client devices. This will help to protect against man-in-the-middle attacks and other types of cyber threats.
* Use a intrusion detection system (IDS): An IDS monitors network traffic and alerts you to any suspicious activity, which can help you to identify and respond to potential threats in a timely manner. - Use a intrusion detection system (IDS): An IDS monitors network traffic and alerts you to any suspicious activity, which can help you to identify and respond to potential threats in a timely manner.
* Enable two-factor authentication: Two-factor authentication adds an extra layer of security to your accounts by requiring a second form of authentication, such as a code sent to your phone, in addition to your password. - Enable two-factor authentication: Two-factor authentication adds an extra layer of security to your accounts by requiring a second form of authentication, such as a code sent to your phone, in addition to your password.
Also learn about OpenSSL and creating your own PKI as well as managing certs, renewals, and mutual client auth with x509 certs Also learn about OpenSSL and creating your own PKI as well as managing certs, renewals, and mutual client auth with x509 certs

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save