Showing preview only (318K chars total). Download the full file or copy to clipboard to get everything.
Repository: elsewhencode/project-guidelines
Branch: master
Commit: 87c9014ec4f9
Files: 15
Total size: 308.3 KB
Directory structure:
gitextract_hg0vvobc/
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README-ir.md
├── README-it.md
├── README-ja.md
├── README-ko.md
├── README-pt-BR.md
├── README-ru.md
├── README-zh.md
├── README.md
├── README.sample.md
├── config.sample.js
└── configWithTest.sample.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
### Node ###
# Logs
logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Optional npm cache directory
.npm
# Dependency directories
/node_modules
/jspm_packages
/bower_components
# Yarn Integrity file
.yarn-integrity
# Optional eslint cache
.eslintcache
# dotenv environment variables file(s)
.env
.env.*
#Build generated
dist/
build/
# Serverless generated files
.serverless/
### SublimeText ###
# cache files for sublime text
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
# workspace files are user-specific
*.sublime-workspace
# project files should be checked into the repository, unless a significant
# proportion of contributors will probably not be using SublimeText
# *.sublime-project
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
### Vim ###
*.sw[a-p]
### WebStorm/IntelliJ ###
/.idea
modules.xml
*.ipr
*.iml
### System Files ###
*.DS_Store
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at vahid@elsewhen.co. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Project Guidelines
### No guidelines here :D, hit us with your PR.
**Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2018 Elsewhen https://www.elsewhen.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README-ir.md
================================================
[中文版](./README-zh.md)
| [日本語版](./README-ja.md)
| [한국어](./README-ko.md)
| [Русский](./README-ru.md)
| [Português](./README-pt-BR.md)
| [Italiana](./README-it.md)
| [English](./README.md)
| [Persian/فارسی](./README-ir.md)
<p align="right">
<a href="https://www.elsewhen.com/">
<img src="./images/elsewhen-logo.png" width="180" height="180">
</a>
</p>
# دستورالعملهای پروژه · [](http://makeapullrequest.com)
> وقتی که شروع و توسعه یک پروژه جدید برای شما شبیه به حرکت در یک میدان سبز و خالی (که هیچ ساختاری ندارد) است (استعاره از شروع کردن یک پروژه یا کار جدید از ابتدا و بدون هیچ محدودیت و ساختاری است)، نگهداری از آن میتواند کابوسی پیچیده و تاریک برای شخص دیگری باشد.
> در اینجا لیستی از دستورالعملها آمده است که ما آنها را پیدا کردهایم، نوشتهایم و گردآوری کردهایم و فکر میکنیم که برای اکثر پروژههای جاوااسکریپت در [elsewhen](https://www.elsewhen.com) به خوبی عمل میکند.
> اگر میخواهید یک روش بهینه را به اشتراک بگذارید، یا فکر میکنید یکی از این دستورالعملها باید حذف شود، [با خیال راحت آن را با ما به اشتراک بگذارید](http://makeapullrequest.com).
<hr>
- [گیت/Git](#git)
- [برخی از قوانین Git](#some-git-rules)
- [گردشکار گیت/Git workflow](#git-workflow)
- [نگارش بهتر متن کامیتها](#writing-good-commit-messages)
- [مستندات](#documentation)
- [متغیرهای محیطی/Environments](#environments)
- [ایجاد محیطهای توسعهی یکپارچه/Consistent dev environments](#consistent-dev-environments)
- [وابستگیهای یکسان و هماهنگ/Consistent dependencies](#consistent-dependencies)
- [وابستگیها/Dependencies](#dependencies)
- [تست کردن/Testing](#testing)
- [ساختار و نامگذاری/Structure and Naming](#structure-and-naming)
- [سبک کدنویسی/Code style](#code-style)
- [برخی از دستورالعملهای code style](#code-style-check)
- [اعمال استانداردهای سبک کدنویسی](#enforcing-code-style-standards)
- [ثبت وقایع/Logging](#logging)
- [ایپیآی/API](#api)
- [طراحی API](#api-design)
- [امنیت ایپیآی/API security](#api-security)
- [مستندسازی ایپیآی/API documentation](#api-documentation)
- [دسترسپذیری/Accessibility](#a11y)
- [مجوزدهی/Licensing](#licensing)
<a name="git"></a>
## 1. گیت/Git
<p align="right">
<img src="/images/branching.png" width="135" height="135">
</p>
<a name="some-git-rules"></a>
### 1.1 برخی از قوانین Git
مجموعهای از قوانین وجود دارد که باید آنها را به خاطر داشته باشید:
- کار را در برنچ feature انجام دهید
_چرا:_
> این روش باعث میشود که تمام کارها به صورت مجزا در یک برنچ اختصاصی انجام شوند، نه در برنچ اصلی. این کار به شما امکان را میدهد تا چندین درخواست Pull Request بدون سردرگمی ارسال کنید. همچنین میتوانید به طور مکرر کد را بهروزرسانی کنید، بدون اینکه برنچ اصلی را با کد ناپایدار و ناتمام آلوده کنید. [توضیحات بیشتر ...](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow)
- از برنچ `develop` انشعاب بگیرید
_چرا:_
> به این ترتیب، میتوانید مطمئن شوید که کد برنچ master تقریباً همیشه بدون مشکل build میشود و معمولاً میتوان آن را مستقیماً برای releases استفاده کرد (این کار ممکن است برای برخی پروژهها بیش از حد لازم باشد).
- هرگز مستقیماً به برنچ `develop` یا `master` پوش نکنید. بلکه یک درخواست Pull Request ایجاد کنید.
_چرا:_
> این کار به اعضای تیم اطلاع میدهد که یک feature تکمیل شده است. همچنین امکان بررسی آسان کد توسط سایرین را فراهم میکند و فضایی برای بحث درباره feature پیشنهادی ایجاد میکند.
- برنچ `develop` محلی/local خود را قبل از پوش کردن یک feature، ابتدا بروزرسانی و مورد بازبینی تعاملی (interactive rebase) قرار دهید، سپس درخواست Pull Request ایجاد کنید.
_چرا:_
> ریبیس (Rebase) برنچ درخواستشده (`master` یا `develop`) را merge میکند و کامیتهایی که بهصورت locally انجام دادهاید را به بالای تاریخچه اعمال میکند، بدون اینکه کامیت merge ایجاد کند (در صورتی که تعارضی وجود نداشته باشد). نتیجه آن یک تاریخچه تمیز و مرتب خواهد بود. [توضیحات بیشتر ...](https://www.atlassian.com/git/tutorials/merging-vs-rebasing)
- تعارضات احتمالی را در حین rebase و قبل از ایجاد درخواست Pull Request برطرف کنید.
- برنچهای feature ایجاد شده در local و remote را پس از ادغام حذف کنید.
_چرا:_
> لیست برنچهای شما را با برنچهای بیاستفاده درهم میآمیزد (شلوغ میکند). حذف برنچهای feature باعث میشود که هر برنچ تنها یکبار به برنچ اصلی (`master` یا `develop`) ادغام شود. برنچهای feature باید فقط تا زمانی که کار هنوز در حال انجام است وجود داشته باشند.
- قبل از ایجاد درخواست Pull Request، مطمئن شوید که برنچ feature شما با موفقیت build میشود و همه testها (شامل بررسیهای سبک/استایل کد) با موفقیت انجام میشود.
_چرا:_
> شما قصد دارید که کد خود را به یک برنچ stable اضافه کنید. اگر testهای برنچ feature شما ناموفق باشند، احتمال زیادی وجود دارد که build برنچ مقصد نیز شکست بخورد. علاوه بر این، قبل از ایجاد درخواست Pull Request، نیاز است که بررسی سبک و استایل کد را انجام شود. این کار باعث بهبود خوانایی کد میشود و احتمال ترکیب شدن تغییرات قالببندی با تغییرات واقعی را کاهش میدهد.
- [از فایل](./.gitignore) `.gitignore` استفاده کنید.
_چرا:_
> این فایل از قبل دارای لیستی از فایلهای سیستمی است که نباید همراه با کد شما به مخزن remote ارسال شوند. علاوه بر این، پوشهها و فایلهای تنظیمات برای بیشتر ویرایشگرهای مورد استفاده و همچنین پوشههای dependency رایج را نیز مستثنی میکند.
- از برنچهای `develop` و `master` محافظت کنید.
_چرا:_
> این کار از برنچهای آماده برای production در برابر دریافت تغییرات غیرمنتظره و غیرقابل بازگشت محافظت میکند. توضیحات بیشتر ... [GitHub](https://help.github.com/articles/about-protected-branches/), [Bitbucket](https://confluence.atlassian.com/bitbucketserver/using-branch-permissions-776639807.html) and [GitLab](https://docs.gitlab.com/ee/user/project/protected_branches.html)
<a name="git-workflow"></a>
### 1.2 گردشکار گیت/Git workflow
به خاطر دلایل ذکرشده در بالا، ما از [Feature-branch-workflow](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow) همراه با [Interactive Rebasing](https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing) و برخی عناصر [Gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows#gitflow-workflow) (نامگذاری و داشتن یک develop branch). استفاده میکنیم. مراحل اصلی به شرح زیر هستند:
- برای یک پروژه جدید، یک مخزن گیت (Git repository) را در پوشه پروژه مقداردهی اولیه کنید. **برای ویژگیها/تغییرات بعدی، این مرحله باید نادیده گرفته شود.**
```sh
cd <project directory>
git init
```
- یک شاخه جدید برای توسعه یک feature یا رفع یک bug ایجاد کنید و به آن منتقل شوید.
```sh
git checkout -b <branchname>
```
- تغییری در آن ایجاد کنید.
```sh
git add <file1> <file2> ...
git commit
```
_چرا:_
> کامند `git add <file1> <file2> ... ` - شما باید فقط فایلهایی را اضافه کنید که یک تغییر کوچک و منسجم را تشکیل میدهند.
> کامند `git commit` یک ویرایشگر باز میکند که به شما اجازه میدهد مقادیر subject را از body در کامیت خود از هم جدا کنید.
> در _بخش 1.3_ بیشتر درباره آن بخوانید.
_نکته:_
> میتوانید به جای آن از دستور `git add -p` استفاده کنید که به شما این امکان را میدهد تمام تغییرات اعمالشده را یک به یک بررسی کنید و تصمیم بگیرید که آیا آنها را در کامیت وارد کنید یا نه.
- با مخزن remote همگامسازی کنید تا تغییراتی که از دست دادهاید را دریافت کنید.
```sh
git checkout develop
git pull
```
_چرا:_
> این کار به شما فرصت میدهد که با conflictها در سیستم خود در حین rebasing برخورد کنید، به جای اینکه یک درخواست Pull Request ایجاد کنید که حاوی conflictها باشد.
- برنچ feature خود را با استفاده از interactive rebase با آخرین تغییرات از برنچ develop بهروزرسانی کنید.
```sh
git checkout <branchname>
git rebase -i --autosquash develop
```
_چرا:_
> میتوانید از `--autosquash` استفاده کنید تا تمام کامیتهای خود را به یک کامیت ترکیب کنید. هیچکس نمیخواهد برای یک ویژگی در شاخه develop چندین کامیت داشته باشد. [توضیحات بیشتر ...](https://robots.thoughtbot.com/autosquashing-git-commits)
- اگر conflicts ندارید، این مرحله را رد کنید. در غیراینصورت، [آنها را حل کنید](https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/) و rebase را ادامه دهید.
```sh
git add <file1> <file2> ...
git rebase --continue
```
- برنچ خود را push کنید. rebase تاریخچه را تغییر میدهد، بنابراین باید از `-f` برای اجبار تغییرات به برنچ remote استفاده کنید. اگر شخص دیگری روی برنچ شما کار میکند، از گزینه کمتر مخرب `--force-with-lease` استفاده کنید.
```sh
git push -f
```
_چرا:_
> وقتی که rebase انجام میدهید، تاریخچه برنچ feature خود را تغییر میدهید. در نتیجه، گیت `git push` معمولی را رد میکند. به جای آن باید از فلگ `-f` یا `--force` استفاده کنید. [توضیحات بیشتر ...](https://developer.atlassian.com/blog/2015/04/force-with-lease/)
- یک درخواست Pull Request ایجاد کنید.
- درخواست Pull Request توسط یک بررسی کننده پذیرفته، ادغام و بسته خواهد شد.
- در صورت اتمام کار، برنچ feature محلی/local خود را حذف کنید.
```sh
git branch -d <branchname>
```
تمام برنچهای local را که در مخزن remote وجود ندارند را حذف کنید. (این کار باعث میشود که برنچهای که دیگر وجود ندارند، از مخزن local حذف شوند، در نتیجه محیط توسعه شما تمیز و مرتب باقی میماند.)
```sh
git fetch -p && for branch in `git branch -vv --no-color | grep ': gone]' | awk '{print $1}'`; do git branch -D $branch; done
```
<a name="writing-good-commit-messages"></a>
### 1.3 نگارش بهتر متن کامیتها
داشتن یک راهنمای مناسب برای ایجاد کامیتها و پایبندی به آن، کار با گیت و همکاری با دیگران را بسیار آسانتر میکند. در اینجا چند قانون کلی وجود دارد:([منبع](https://chris.beams.io/posts/git-commit/#seven-rules)):
- موضوع (subject) را از بدنه (body) جدا کنید و بین این دو یک خط خالی قرار دهید.
_چرا:_
> گیت به اندازه کافی هوشمند است که خط اول پیام کامیت شما را بهعنوان خلاصه تشخیص دهد. در واقع، اگر بهجای استفاده از git log از git shortlog استفاده کنید، یک لیست طولانی از پیامهای کامیت خواهید دید که شامل شناسه کامیت و تنها خلاصه پیام است.
- طول خط موضوع (subject) را به ۵۰ کاراکتر محدود کنید و بدنه پیام را در ۷۲ کاراکتر بشکنید.
_چرا:_
> کامیتها تا حد ممکن باید جزئی و متمرکز باشند؛ نیازی به طولانینویسی در آنها نیست. [توضیحات بیشتر ...](https://medium.com/@preslavrachev/what-s-with-the-50-72-rule-8a906f61f09c)
- حرف اول موضوع (subject) را با عبارت بزرگ (Capitalize) شروع کنید.
- موضوع (subject) را با نقطه تمام نکنید.
- از [وجه امری](https://en.wikipedia.org/wiki/Imperative_mood) در موضوع (subject) استفاده کنید.
_چرا:_
> به جای نوشتن پیامهایی که فقط بیانگر/توصیفکننده کاری است که کامیتکننده انجام داده، بهتر است این پیامها را به عنوان دستورالعملهایی در نظر بگیرید که بیان میکنند پس از اعمال کامیت در مخزن، چه چیزی قرار است انجام شود. (توضیح مترجم: پیامهای کامیت باید بر نتیجه و هدف تمرکز کنند، نه صرفاً بر عملیات انجامشده.) [توضیحات بیشتر ...](https://news.ycombinator.com/item?id=2079612)
- از قسمت بدنه (body) برای توضیح **چه کاری** و **چرا** انجام شده، استفاده کنید، نه **چگونگی** انجام آن.
<a name="documentation"></a>
## 2. مستندات
<p align="right">
<img src="/images/documentation.png" alt="Documentation" width="128" height="128">
</p>
- از این [قالب](./README.sample.md) برای فایل `README.md` استفاده کنید؛ اگر بخشهایی وجود دارد که پوشش داده نشدهاند، با خیال راحت آنها را اضافه کنید.
- برای پروژههایی که بیش از یک مخزن (repository) دارند، لینک به مخازن دیگر را در فایلهای `README.md` مربوطه قرار دهید..
- با پیشرفت پروژه، فایل `README.md` را بهروز نگه دارید.
- کد خود را کامنتگذاری کنید. سعی کنید با هر بخش اصلی کد، بهوضوح توضیح دهید که قصد دارید چه کاری انجام دهید.
- اگر درباره کد یا روش مورد استفاده شما در گیتهاب یا استکاورفلو بحثی باز وجود دارد، لینک آن را در کامنت خود بگنجانید.
- از کامنتها بهعنوان توجیهی برای کد ضعیف استفاده نکنید. کد خود را تمیز نگه دارید.
- از کد تمیز بهعنوان بهانهای برای عدم کامنتگذاری استفاده نکنید.
- با پیشرفت کد، کامنتها را نیز متناسب بهروز نگه دارید.
<a name="environments"></a>
## 3. متغیرهای محیطی/Environments
<p align="right">
<img src="/images/laptop.png" alt="Environments" width="128" height="128">
</p>
- در صورت نیاز، environmentهای جداگانهای برای `development`، `test` و `production` تعریف کنید.
_چرا:_
> در محیطها (environments) مختلف ممکن است data، tokens، APIs، ports و... متفاوتی نیاز باشند. ممکن است بخواهید یک حالت `development` ایزوله داشته باشید که به APIهای جعلی متصل میشود و دادههای قابل پیشبینی برمیگرداند، که این کار هم تستهای خودکار و هم تستهای دستی را بسیار سادهتر میکند. یا شاید بخواهید Google Analytics را فقط در محیط `production` فعال کنید و به همین ترتیب.
> [توضیحات بیشتر ...](https://stackoverflow.com/questions/8332333/node-js-setting-up-environment-specific-configs-to-be-used-with-everyauth)
- پیکربندیهای مختص هر محیط اجرایی را از متغیرهای محیطی (environment variables) بارگذاری کنید و هرگز آنها را بهعنوان مقادیر ثابت در کد قرار ندهید. [به این نمونه نگاه کنید](./config.sample.js).
_چرا:_
> در این فایلها ممکن است tokens، passwords و دیگر اطلاعات ارزشمند وجود داشته باشند. پیکربندی/کانفیگ شما باید بهدرستی از بخشهای داخلی برنامه جدا باشد، به گونهای که کد در هر لحظه ممکن است عمومی شود.
_چگونه:_
> فایلهای `.env` را برای ذخیره متغیرهای خود استفاده کنید و آنها را به `.gitignore` اضافه کنید تا از مخزن مستثنی شوند. در عوض، یک فایل `.env.example` کامیت کنید که بهعنوان راهنما برای توسعهدهندگان عمل کند. برای محیط production، باید همچنان متغیرهای محیطی را به روش استاندارد تنظیم کنید. [بیشتر بخوانید](https://medium.com/@rafaelvidaurre/managing-environment-variables-in-node-js-2cb45a55195f)
- توصیه میشود قبل از شروع برنامه، متغیرهای محیطی را اعتبارسنجی کنید. [این نمونه را مشاهده کنید](./configWithTest.sample.js) که از `joi` برای اعتبارسنجی مقادیر ارائهشده استفاده میکند.
_چرا:_
> این کار میتواند دیگران را از ساعتها مشکلیابی/troubleshooting نجات دهد.
> <a name="consistent-dev-environments"></a>
### 3.1 ایجاد محیطهای توسعهی یکپارچه/Consistent dev environments:
- نسخهی Node خود را در بخش `engines` در فایل `package.json` تنظیم کنید..
_چرا:_
> این کار به دیگران اطلاع میدهد که پروژه با کدام نسخهی Node کار میکند. [توضیحات بیشتر ...](https://docs.npmjs.com/files/package.json#engines)
- همچنین از `nvm` استفاده کنید و یک فایل `.nvmrc` در ریشهی پروژهی خود ایجاد کنید. فراموش نکنید که به آن در مستندات اشاره کنید.
_چرا:_
> هر کسی که از `nvm` استفاده میکند، میتواند به سادگی با اجرای کامند `nvm use` به نسخهی مناسب Node سوئیچ کند. [توضیحات بیشتر ...](https://github.com/creationix/nvm)
- تنظیم یک اسکریپت `preinstall` که نسخههای Node و npm را بررسی کند، ایدهی خوبی است.
_چرا:_
> برخی وابستگیها/dependencies ممکن است در صورت نصب توسط نسخههای جدیدتر npm با خطا مواجه شوند.
- در صورت امکان از Docker استفاده کنید.
_چرا:_
> این کار میتواند یک محیط سازگار در کل فرآیند کاری شما فراهم کند، بدون نیاز به تنظیمات یا وابستگیهای پیچیده. [توضیحات بیشتر ...](https://hackernoon.com/how-to-dockerize-a-node-js-application-4fbab45a0c19)
- از پکیجهای محلی/local بهجای پکیجهای نصبشده بهصورت گلوبالی/globally استفاده کنید.
_چرا:_
> این کار به شما اجازه میدهد پکیجهای خود را با همکارانتان به اشتراک بگذارید، به جای اینکه انتظار داشته باشید آنها را بهصورت گلوبالی روی سیستم خود نصب کرده باشند.
<a name="consistent-dependencies"></a>
### 3.2 وابستگیهای یکسان و هماهنگ/Consistent dependencies:
- اطمینان حاصل کنید که اعضای تیم دقیقاً همان وابستگیها (dependencies) را مانند شما دریافت کنند.
_چرا:_
> زیرا میخواهید که کد، در هر محیط توسعهای به همان شکل مورد انتظار عمل کند و یکسان باشد. [توضیحات بیشتر ...](https://kostasbariotis.com/consistent-dependencies-across-teams/)
_چگونه:_
> از `package-lock.json` در نسخه 5 از `npm` یا بالاتر، استفاده کنید.
_من npm@5 ندارم:_
> در این صورت میتوانید از `Yarn` استفاده کنید و اطمینان حاصل کنید که این موضوع را در فایل `README.md`. پس از هر بهروزرسانی وابستگیها، lock file و `package.json` باید نسخههای یکسانی داشته باشند. [توضیحات بیشتر ...](https://yarnpkg.com/en/)
_من اسم `Yarn` را دوست ندارم:_
> متأسفانه انتخاب دیگری ندارید. برای نسخههای قدیمیتر `npm`, هنگام نصب وابستگی جدید از `—save --save-exact` استفاده کنید و قبل از انتشار پروژه، فایل `npm-shrinkwrap.json` ایجاد کنید. [توضیحات بیشتر ...](https://docs.npmjs.com/files/package-locks)
<a name="dependencies"></a>
## 4. وابستگیها/Dependencies
<p align="right">
<img src="/images/modules.png" alt="modules" width="128" height="128">
</p>
- بر روی پکیجهای فعلی خود را که در حال حاضر در دسترس هستند، پیگیری و نظارت کنید: به عنوان مثال، از دستور `npm ls --depth=0` استفاده کنید. (توضیحات مترجم: با استفاده از دستور `npm ls --depth=0` در محیط خط فرمان، میتوانید فهرستی از پکیجهای سطح اول (بدون نمایش وابستگیهای زیرمجموعهای) را مشاهده کنید. این کار به شما کمک میکند تا بدانید چه بستههایی در حال حاضر در پروژهتان نصب هستند و از وضعیت آنها مطلع باشید.) [توضیحات بیشتر ...](https://docs.npmjs.com/cli/ls)
- بررسی کنید آیا هیچیک از پکیجهای شما بیاستفاده یا نامربوط (غیرضروری یا غیرکاربردی) شدهاند: با استفاده از ابزار `depcheck` [توضیحات بیشتر ...](https://www.npmjs.com/package/depcheck)
_چرا:_
> ممکن است یک کتابخانه بیاستفاده را در کد خود داشته باشید که باعث افزایش حجم نهایی برنامه شود. وابستگیهای بیاستفاده را پیدا کرده و حذف کنید.
- قبل از استفاده از یک وابستگی، آمار دانلود آن را بررسی کنید تا ببینید آیا توسط جامعه بهطور گستردهای استفاده میشود یا خیر: با استفاده از ابزار `npm-stat`. [توضیحات بیشتر ...](https://npm-stat.com/)
_چرا:_
> استفاده بیشتر (از پکیجها) معمولاً به معنای داشتن تعداد بیشتری از مشارکتکنندگان است که اغلب منجر به نگهداری بهتر میشود و همه اینها باعث میشود که باگها سریعتر کشف و اصلاحات سریعتر توسعه داده شوند.
- پیش از استفاده از یک وابستگی، بررسی کنید که آیا آن وابستگی نسخههای منظم و پایداری ارائه میدهد و تعداد زیادی نگهدارندگان (maintainers) دارد یا نه. به عنوان مثال، میتوانید از دستور `npm view async` استفاده کنید. [توضیحات بیشتر ...](https://docs.npmjs.com/cli/view)
_چرا:_
> داشتن تعداد زیادی از مشارکتکنندگان زمانی مؤثر است که نگهدارندگان بتوانند اصلاحات و تغییرات را به سرعت merge کنند.
- اگر به وابستگی کمتر شناخته شدهای (غیرمشهور) نیاز دارید، قبل از استفاده از آن، با تیم خود مشورت کنید.
- همیشه مطمئن شوید که برنامه شما با آخرین نسخه از وابستگیهایش بدون هیچگونه مشکلی/خرابی کار میکند: از دستور `npm outdated` استفاده کنید. [توضیحات بیشتر ...](https://docs.npmjs.com/cli/outdated)
_چرا:_
> بروزرسانی وابستگیها (dependencies) گاهی شامل تغییرات مخرب میشوند. هر زمان که بروزرسانیها نمایش داده میشوند، حتماً release note ها را بررسی کنید. وابستگیهای (dependencies) خود را یکییکی بروزرسانی کنید، زیرا اگر مشکلی پیش بیاید، عیبیابی آن آسانتر خواهد بود. از ابزارهای کاربردی مانند موارد زیر استفاده کنید: [npm-check-updates](https://github.com/tjunnone/npm-check-updates).
- بررسی کنید که آیا بسته موردنظر مشکلات امنیتی شناختهشدهای دارد یا خیر؛ به عنوان مثال، با استفاده از [Snyk](https://snyk.io/test?utm_source=risingstack_blog).
<a name="testing"></a>
## 5. تست کردن/Testing
<p align="right">
<img src="/images/testing.png" alt="testing" width="128" height="128">
</p>
- در صورت نیاز، یک environment به نام `test` (برای حالت تست) ایجاد کنید.
_چرا:_
> گاهی تست end to end در حالت `production` ممکن است کافی به نظر برسد، اما در موارد خاص نیاز به محیط تست جداگانهای وجود دارد. مثلاً ممکن است نخواهید اطلاعات تحلیلی در حالت `production` فعال شود و داشبورد افراد را با دادههای تست آلوده کنید. (توضیحات مترجم: چون دادههای تستی ممکن است اطلاعات واقعی را تحت تأثیر قرار دهد، مثلا باعث شلوغی و ایجاد دادههای غیرضروری شوند و یا مانع از درک دقیق اطلاعات واقعی توسط کاربران یا تیم تحلیل شوند.) مثال دیگر این است که ممکن است API شما در حالت تولید محدودیت تعداد درخواست (rate limit) داشته باشد و پس از تعداد مشخصی درخواست، فراخوانی APIها توسط تست را مسدود کند.
- فایلهای تست خود را در کنار ماژولهای مورد آزمایش با استفاده از الگوی نامگذاری خاصی `*.test.js` یا `*.spec.js` قرار دهید، مانند `moduleName.spec.js`.
_چرا:_
> برای پیدا کردن یک تست واحد، در ساختار پوشهها جستجو و پیمایش نکنید. [توضیحات بیشتر ...](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc)
- برای جلوگیری از سردرگمی، فایلهای تست اضافی خود را پر یک پوشه جداگانه قرار دهید.
_چرا:_
> برخی از فایلهای تست مستقیماً به فایل پیادهسازی خاصی مرتبط نیستند. باید این فایلها را در پوشهای قرار دهید که احتمالاً توسط سایر توسعهدهندگان به راحتی یافت شود: پوشه `__test__`. این نام `__test__` هم اکنون یک استاندارد است و توسط اکثر فریمورکهای تست جاوااسکریپت تشخیص داده میشود.
- کد قابل تست بنویسید، از اثرات جانبی (side effect) خودداری کنید، اثرات جانبی را جدا کنید، و توابع خالص (pure functions) بنویسید.
_چرا:_
> هر بخش از منطق کسبوکار (business logic) باید به صورت مستقل و جداگانه مورد آزمایش و تست قرار گیرد تا مطمئن شوید که هر قسمت به درستی کار میکند. باید "تأثیر عوامل تصادفی یا فرآیندهای غیرقابلپیشبینی را در کد به حداقل برسانید" [توضیحات بیشتر ...](https://medium.com/javascript-scene/tdd-the-rite-way-53c9b46f45e3)
> یک تابع خالص (pure function) تابعی است که همیشه برای ورودی یکسان، خروجی یکسانی را باز میگرداند. برعکس، یک تابع ناخالص (impure function) تابعی است که ممکن است اثرات جانبی داشته باشد یا برای تولید یک مقدار به شرایط خارجی وابسته باشد، که این امر باعث میشود کمتر قابل پیشبینی باشد. [توضیحات بیشتر ...](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc)
- از یک static type checker استفاده کنید
_چرا:_
> گاهی ممکن است به یک Static type checker نیاز داشته باشید. این ابزارها، سطحی از قابلیت اطمینان را برای کد شما به ارمغان میآورند. [توضیحات بیشتر ...](https://medium.freecodecamp.org/why-use-static-types-in-javascript-part-1-8382da1e0adb)
- قبل از آنکه درخواست pull request به برنچ `develop` را ارسال کنید، تستها را بهصورت locally اجرا کنید.
_چرا:_
> قطعاً نمیخواهید کسی باشید که باعث شکست فرایند بیلد برنچ آمادهی production شده است. تستهای خود را پس از `rebase` و پیش از ارسال به شاخه feature-branch به مخزن ریموت اجرا کنید.
- تستهای خود را از جمله دستورالعملهای مربوطه در بخش مناسب فایل `README.md` پروژه را مستندسازی کنید.
_چرا:_
> این مستندات مانند یک یادداشت راهنما است که برای توسعهدهندگان دیگر، کارشناسان DevOps، یا تیم تضمین کیفیت (QA) و هر کسی که با کد شما کار میکند، مفید خواهد بود.
<a name="structure-and-naming"></a>
## 6. ساختار و نامگذاری/Structure and Naming
<p align="right">
<img src="/images/folder-tree.png" alt="Structure and Naming" width="128" height="128">
</p>
- فایلهای خود را بر اساس ویژگیهای محصول / صفحات / کامپوننتها سازماندهی کنید، نه بر اساس نقشها. همچنین فایلهای تست را در کنار آنها قرار دهید.
**بد**
```
.
├── controllers
| ├── product.js
| └── user.js
├── models
| ├── product.js
| └── user.js
```
**خوب**
```
.
├── product
| ├── index.js
| ├── product.js
| └── product.test.js
├── user
| ├── index.js
| ├── user.js
| └── user.test.js
```
_چرا:_
> به جای داشتن لیست طولانی از فایلها، ماژولهای کوچک ایجاد کنید که هر کدام یک مسئولیت خاص را دربرمیگیرند، از جمله تست آنها و موارد دیگر. این کار باعث میشود دسترسی به فایلها سادهتر شده و بتوانید به سرعت و با یک نگاه فایلهای مورد نظر را پیدا کنید.
- فایلهای تست اضافی خود را در یک پوشهی جداگانه به نام test قرار دهید تا از سردرگمی جلوگیری شود.
_چرا:_
> این کار برای سایر توسعهدهندگان یا کارشناسان DevOps تیم شما موجب صرفهجویی در زمان میشود.
- از یک پوشه به نام `./config` برای تنظیمات استفاده کنید و فایلهای پیکربندی جداگانه برای محیطها (environments) مختلف ایجاد نکنید.
_چرا:_
> زمانی که یک فایل کانفیگ را برای اهداف مختلف (مانند پایگاه داده، API و غیره) تجزیه میکنید، قرار دادن آنها در پوشهای با نام مشخص مانند `config` منطقی است. فقط به خاطر داشته باشید که برای محیطهای مختلف فایلهای جداگانه نسازید، زیرا با افزایش استقرارهای برنامه، نامهای محیط جدیدی مورد نیاز میشود و مدیریت آن پیچیده خواهد شد.
> مقادیر مورد استفاده در فایلهای کانفیگ باید از طریق متغیرهای محیطی (environment variables) فراهم شوند. [توضیحات بیشتر ...](https://medium.com/@fedorHK/no-config-b3f1171eecd5)
- اسکریپتهای خود را در یک پوشه به نام `./scripts` قرار دهید. این شامل اسکریپتهای `bash` و `node` است.
_چرا:_
> احتمالاً به بیش از یک اسکریپت نیاز خواهید داشت، مانند production build, development build, database feeders, database synchronization و غیره.
- خروجی بیلد خود را در یک پوشه به نام `./build` قرار دهید. `build/` را به `.gitignore` اضافه کنید.
_چرا:_
> نامگذاری آن به سلیقه شما بستگی دارد، `dist` نیز گزینه خوبی است. اما با تیم خود این نامگذاری را هماهنگ کنید. فایلهایی که در این پوشه قرار میگیرند معمولاً تولید شدهاند (bundled, compiled, transpiled) یا به این پوشه منتقل شدهاند. چیزی که میتوانید تولید کنید، همتیمیهای شما نیز باید قادر به تولید آن باشند؛ بنابراین نیازی به ارسال آنها به مخزن ریموت نیست، مگر اینکه هدف خاصی داشته باشید.
<a name="code-style"></a>
## 7. سبک کدنویسی/Code style
<p align="right">
<img src="/images/code-style.png" alt="Code style" width="128" height="128">
</p>
<a name="code-style-check"></a>
### 7.1 برخی از اصول code style
- برای پروژههای جدید از سینتکس جاوااسکریپت مدرن (استیج ۲ و بالاتر) استفاده کنید. برای پروژههای قدیمی، با سینتکس موجود سازگار بمانید مگر اینکه قصد بهروزرسانی آن را داشته باشید.
_چرا:_
> این موضوع به تصمیم شما بستگی دارد. ما از مبدلها (ترنسپایلرها) برای بهرهگیری از مزایای سینتکس جدید استفاده میکنیم. استیج ۲ با تغییرات جزئی احتمالا بخشی از استاندارد خواهد شد.
- اطمینان حاصل کنید که بررسی سبک کدنویسی (code style) به عنوان بخشی از فرآیند build پروژه انجام شود. (تا هماهنگی و استاندارد بودن کدها در تمام مراحل توسعه حفظ شود.)
_چرا:_
> متوقف کردن build برنامه یکی از روشهای اعمال سبک کدنویسی در کد است. این کار از بیتوجهی به سبک کدنویسی جلوگیری میکند. این روش را برای کد سمت client و server اجرا کنید. [توضیحات بیشتر ...](https://www.robinwieruch.de/react-eslint-webpack-babel/)
- برای اعمال سبک کدنویسی از [ESLint - ابزار بررسی سبک کدنویسی جاوااسکریپت](http://eslint.org/) استفاده کنید.
_چرا:_
> ما `eslint` را ترجیح میدهیم، اما شما میتوانید انتخاب دیگری داشته باشید. این ابزار قوانین بیشتری را پشتیبانی میکند، همچنین قابلیت تنظیم و افزودن قوانین سفارشی را دارد.
- ما از کد استایل [Airbnb](https://github.com/airbnb/javascript) برای جاوااسکریپت استفاده میکنیم، [بیشتر بخوانید](https://www.gitbook.com/book/duk/airbnb-javascript-guidelines/details). از کد استایلی که پروژه یا تیم شما نیاز دارد استفاده کنید (تا کدهایتان با استانداردهای تعیینشده هماهنگ باشند).
- ما هنگام استفاده از [FlowType](https://flow.org/) از [قوانین بررسی سبک تایپ Flow برای ESLint](https://github.com/gajus/eslint-plugin-flowtype) استفاده میکنیم.
_چرا:_
> ابزار Flow سینتکسهای جدیدی را معرفی میکند که نیاز به رعایت سبک کدنویسی خاصی دارند و باید بررسی شوند.
- از فایل `.eslintignore` برای مستثنی کردن فایلها یا پوشهها از بررسی کد استایل استفاده کنید.
_چرا:_
> برای مستثنی کردن چند فایل از بررسی سبک کدنویسی، لازم نیست کدتان را با کامنتهای `eslint-disable` شلوغ کنید.
- قبل از ارسال یک Pull Request، تمام کامنتهای `eslint-disable` خود را حذف کنید.
_چرا:_
> طبیعی است که هنگام کار بر روی یک بخش از کد، برای تمرکز بیشتر روی منطق، بررسی سبک را غیرفعال کنید. فقط به خاطر داشته باشید که کامنتهای `eslint-disable` را حذف کرده و قوانین را رعایت کنید.
- بسته به حجم و اندازه کار، از کامنتهای `//TODO:` استفاده کنید یا یک تیکت باز کنید.
_چرا:_
> استفاده از کامنتهای `//TODO:` به شما و همکارانتان کمک میکند تا وظایف کوچک مانند بازنویسی یک تابع یا بهروزرسانی یک توضیح را به خاطر بسپارید. برای وظایف بزرگتر، از فرمت `//TODO(#3456)` استفاده کنید که توسط قوانین lint اعمال میشود، که شمارهی داخل پرانتز به یک تیکت باز اشاره دارد.
- همیشه کامنتها را بهروز و مرتبط با تغییرات کد نگه دارید. بخشهای کامنتشده کد را حذف کنید.
_چرا:_
> کد شما باید تا حد ممکن خوانا باشد؛ هر چیزی که حواس را پرت میکند، حذف کنید. اگر یک تابع را بازنویسی کردید، تابع قدیمی را فقط کامنت نکنید، بلکه آن را حذف کنید.
- از کامنتها، لاگها یا نامهای نامرتبط یا طنزآمیز پرهیز کنید.
_چرا:_
> اگرچه در فرآیند build برنامه آن شوخیها ممکن است (و بهتر است بگویم باید) حذف شود، اما گاهی source code شما به شرکت یا مشتری دیگری منتقل میشود که ممکن است آنها چنین شوخیهایی را نپسندند.
- نامها را به گونهای انتخاب کنید که قابل جستوجو و دارای تفاوتهای معنادار باشند و از نامهای کوتاهشده و مخفف بپرهیزید. برای توابع، از نامهای طولانی و توصیفی استفاده کنید. نام تابع باید یک فعل یا عبارت فعلی باشد و هدف آن را به وضوح بیان کند.
_چرا:_
> این کار (استفاده از نامهای کامل و توصیفی) باعث میشود کد خواناتر و درک آن راحتتر و سادهتر شود.
- توابع خود را در فایل بر اساس «قانون نزولی» (Step-down Rule) سازماندهی کنید؛ به این صورت که توابع سطح بالاتر در بالای فایل و توابع سطح پایینتر در زیر آنها قرار گیرند.
_چرا:_
> این کار کد را خواناتر و درک آن بهتر میکند
<a name="enforcing-code-style-standards"></a>
### 7.2 اعمال استانداردهای سبک کدنویسی
- از فایل [.editorconfig](http://editorconfig.org/) استفاده کنید که به توسعهدهندگان کمک میکند تا سبکهای کدنویسی یکسانی را بین ویرایشگرها و IDEهای مختلف پروژه تعریف و حفظ کنند.
_چرا:_
> پروژه EditorConfig شامل یک فرمت فایل برای تعریف سبک و استالهای کدنویسی است که شامل مجموعهای از افزونهها برای ویرایشگرهای متنی است، که به ویرایشگرها این امکان را میدهد تا فرمت فایل را بخوانند و از استایلهای تعریفشده پیروی کنند. فایلهای EditorConfig خوانا هستند و بهخوبی با سیستمهای کنترل نسخه کار میکنند.
- ویرایشگر خود را طوری تنظیم کنید که به شما در مورد خطاهای سبک کدنویسی اطلاع دهد. از [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) و [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) همراه با پیکربندی ESLint خود استفاده کنید. [توضیحات بیشتر ...](https://github.com/prettier/eslint-config-prettier#installation)
- استفاده از Git hooks را مدنظر قرار دهید.
_چرا:_
> استفاده از Git hooks بهطور قابلتوجهی بهرهوری توسعهدهندگان را افزایش میدهد. با اعمال تغییرات، انجام commit و ارسال (push) به محیطهای staging یا production، بدون نگرانی از خراب شدن build برنامه، میتوانید با اطمینان بیشتری کار کنید. [توضیحات بیشتر ...](http://githooks.com/)
- از Prettier همراه با یک precommit hook استفاده کنید.
_چرا:_
> اگرچه `prettier` بهخودیخود قدرتمند است، اجرای دستی آن بهعنوان یک تسک npm برای قالببندی کد چندان کارآمد نیست. در اینجا `lint-staged` (و `husky`) وارد عمل میشوند. درباره پیکربندی `lint-staged` [اینجا](https://github.com/okonet/lint-staged#configuration) و پیکربندی `husky` [اینجا](https://github.com/typicode/husky) بیشتر بخوانید..
<a name="logging"></a>
## 8. ثبت وقایع/Logging
<p align="right">
<img src="/images/logging.png" alt="Logging" width="128" height="128">
</p>
- از استفاده از console.log در سمت کلاینت در محیط production خودداری کنید.
_چرا:_
> حتی اگر فرآیند build برنامه شما میتواند (و باید) آن لاگها را حذف کند، اطمینان حاصل کنید که ابزار بررسی استایل کدنویسی شما دربارهی باقیماندههای console.log هشدار میدهد.
- برای تولید لاگهای خوانا در محیط production، بهتر است از کتابخانههای logging مناسب (مانند [winston](https://github.com/winstonjs/winston) یا [node-bunyan](https://github.com/trentm/node-bunyan)) استفاده کنید.
_چرا:_
> این کار عیبیابی را آسانتر و دلپذیرتر میکند، چون میتوانید از قابلیتهایی مانند رنگبندی، افزودن زمان به لاگها، ثبت لاگها در فایل علاوه بر کنسول و حتی ثبت لاگها در فایلهایی که بهصورت روزانه ایجاد و بایگانی میشوند، استفاده کنید. [توضیحات بیشتر ...](https://blog.risingstack.com/node-js-logging-tutorial/)
<a name="api"></a>
## 9. ایپیآی/API
<a name="api-design"></a>
<p align="right">
<img src="/images/api.png" alt="API" width="128" height="128">
</p>
### 9.1 طراحی API
_چرا:_
> هدف این است که رابطهای RESTfulی طراحی کنیم که منطقی و ساده باشند تا اعضای تیم و مشتریان بتوانند بهسادگی و بهصورت یکنواخت از آنها استفاده کنند.
_چرا:_
> نبود هماهنگی و سادگی میتواند هزینههای یکپارچهسازی و نگهداری را به طور چشمگیری افزایش دهد؛ به همین دلیل طراحی `API` در این داکیومنت گنجانده شده است.
- ما عمدتاً از طراحی مبتنی بر منابع (Resource-Oriented Design) پیروی میکنیم که سه عنصر اصلی دارد: منابع (Resource)، مجموعهها (Collection) و URLها.
- یک منبع شامل دادههایی است که میتواند به صورت تو در تو (nested) سازماندهی شود و متدهایی برای عملیات روی آن وجود دارد.
- گروهی از منابع، یک مجموعه نامیده میشود.
- آدرس اینترنتی (URL) که مکان آنلاین یک منبع یا مجموعه را مشخص میکند.
_چرا:_
> این یک طراحی بسیار شناختهشده برای توسعهدهندگان است (که اصلیترین مصرفکنندگان API هستند). علاوه بر خوانایی و سهولت استفاده، این روش به ما اجازه میدهد کتابخانهها و connectorهای عمومی بنویسیم بدون اینکه نیاز به شناخت جزئیات خاص هر API داشته باشیم.
- برای URLها از kebab-case استفاده کنید.
- برای پارامترهای query string یا فیلدهای منابع از camelCase استفاده کنید.
- از اسامی جمع به صورت kebab-case برای نام منابع در URLها استفاده کنید.
- همیشه از اسامی جمع برای نامگذاری URLهایی که به یک مجموعه اشاره دارند استفاده کنید: `/users`.
_چرا:_
> اساساً، این کار خوانایی را بهتر کرده و URLها را هماهنگ نگه میدارد. [توضیحات بیشتر ...](https://apigee.com/about/blog/technology/restful-api-design-plural-nouns-and-concrete-names)
- در سورس کد، اسامی جمع را به متغیرها و پراپرتیها با پسوند «List» تبدیل کنید.
_چرا:_:
> استفاده از اسامی جمع در URL مناسب است، اما در سورس کد ممکن است نامحسوس و مستعد خطا باشد.
- همیشه از مفاهیم مفرد استفاده کنید که با یک مجموعه شروع شده و به یک شناسه ختم میشوند:
```
/students/245743
/airports/kjfk
```
- از تولید URLهایی مانند زیر اجتناب کنید:
```
GET /blogs/:blogId/posts/:postId/summary
```
_چرا:_
> این URL به جای ارجاع به یک منبع (resource)، به یک ویژگی (property) اشاره میکند. شما میتوانید ویژگی مورد نظر را بهعنوان یک پارامتر در درخواست ارسال کنید تا پاسخ دریافتی مختصرتر و بهینهتر باشد.
- افعال را از URLهای منابع خود حذف کنید.
_چرا:_
> زیرا اگر برای هر عملیات resource از یک فعل استفاده کنید، به زودی با لیستی بزرگ از URLها مواجه خواهید شد که الگوی ثابتی ندارند و یادگیری را برای توسعهدهندگان دشوار میکنند. علاوه بر این، ما از افعال برای چیز دیگری استفاده میکنیم.
- از افعال برای موارد غیر منبع (non-resources) استفاده کنید. در این حالت، API شما هیچ منبعی برنمیگرداند. در عوض، یک عملیات را اجرا کرده و نتیجه را برمیگرداند. اینها عملیات CRUD (ایجاد، بازیابی، بهروزرسانی و حذف) **نیستند**:
```
/translate?text=Hallo
```
_چرا:_
> زیرا برای CRUD ما از متدهای HTTP بر روی URLهای `resource` یا `collection` استفاده میکنیم. افعالی که درباره آنها صحبت میکنیم در واقع کنترلرها `Controllers` هستند. شما معمولاً تعداد زیادی از اینها را توسعه نمیدهید. [توضیحات بیشتر ...](https://github.com/byrondover/api-guidelines/blob/master/Guidelines.md#controller)
- اگر بدنه درخواست (request body) یا پاسخ (response) از نوع `JSON` است، لطفاً برای نامگذاری پراپرتیهای JSON از `camelCase` پیروی کنید تا یکپارچگی و سازگاری حفظ شود.
_چرا:_
> این یک راهنما و دستورالعمل برای پروژه JavaScript است، که فرض بر این است که زبان برنامهنویسی مورد استفاده برای تولید و تجزیه JSON، جاوااسکریپت میباشد.
- با وجود اینکه یک منبع (resource) مفهومی یکتا و مفرد است که مشابه با یک نمونه شیء یا رکورد پایگاه داده است، شما نباید از نام جدول (`table_name`) برای نامگذاری منبع و از نام ستون (`column_name`) برای پراپرتیهای منبع استفاده کنید. به عبارت دیگر، نامگذاری منابع و پراپرتیهای آنها نباید مستقیماً از ساختار پایگاه داده مشتق شود؛ بلکه باید بر اساس مفاهیم و نیازهای دامنهی کاربرد طراحی شود تا از وابستگی به جزئیات پیادهسازی جلوگیری شود.
_چرا:_
> زیرا هدف شما نمایش منابع است، نه جزئیات ساختار پایگاه داده.
- دوباره تکرار میکنم، فقط از اسمها در URL خود هنگام نامگذاری منابع استفاده کنید و سعی نکنید عملکرد آنها را توضیح دهید.
_چرا:_
> فقط از اسامی در URLهای منبع استفاده کنید و از نوشتن مواردی مانند `/addNewUser` یا `/updateUser` خودداری کنید. همچنین از ارسال عملیات منابع بهعنوان پارامتر اجتناب کنید.
- عملکردهای CRUD را با استفاده از متدهای HTTP توضیح دهید:
_چگونه:_
> متد `GET`: برای دریافت از یک resource استفاده میشود.
> متد `POST`: برای ایجاد منابع (resources) جدید و زیرمنابع (sub-resources) به کار میرود.
> متد `PUT`: برای بهروزرسانی منابع موجود استفاده میشود.
> متد `PATCH`: برای بهروزرسانی جزئی منابع موجود به کار میرود؛ بهطوریکه فقط فیلدهای ارائهشده را بهروزرسانی کرده و سایر فیلدها را بدون تغییر باقی میگذارد.
> متد `DELETE`: برای حذف منابع موجود استفاده میشود.
- برای منابع تو در تو (Nested Resources)، توصیه میشود رابطه بین آنها را در ساختار URL منعکس کنید. بهعنوان مثال، برای نمایش ارتباط بین یک کارمند و شرکت مربوطه، میتوانید از شناسهها (`id`) در URL استفاده کنید.
_چرا:_
> این روش دسترسی به منابع مرتبط را آسانتر میکند.
_چگونه:_
> درخواست `GET /schools/2/students` , باید لیست تمام دانشآموزان مدرسه با شناسه ۲ را برگرداند.
> درخواست `GET /schools/2/students/31` , باید جزئیات دانشآموز با شناسه ۳۱ را که متعلق به مدرسه ۲ است، برگرداند.
> درخواست `DELETE /schools/2/students/31` , باید دانشآموز با شناسه ۳۱ را که متعلق به مدرسه ۲ است، حذف کند.
> درخواست `PUT /schools/2/students/31` , باید اطلاعات دانشآموز با شناسه ۳۱ را که متعلق به مدرسه ۲ است، بهروزرسانی کند.
> درخواست `POST /schools` , باید یک مدرسه جدید ایجاد کرده و جزئیات مدرسه تازه ایجاد شده را برگرداند. از POST بر روی URLهای مجموعهای (Collection) استفاده کنید.
- برای نسخهدهی، از یک شماره ترتیبی ساده با پیشوند `v` استفاده کنید (مانند v1، v2) و آن را تا حد امکان در ابتدای URL قرار دهید تا دامنه بالاتری را (برای تاثیرگذاری) داشته باشد:
```
http://api.domain.com/v1/schools/3/students
```
_چرا:_
> وقتی APIهای شما بهطور عمومی برای سایر اشخاص ثالث در دسترس هستند، اعمال تغییرات ناسازگار (breaking changes)، میتواند باعث اختلال در عملکرد محصولات یا خدماتی شود که از APIهای شما استفاده میکنند. استفاده از نسخهبندی در URL میتواند از بروز چنین مشکلاتی جلوگیری کند. [توضیحات بیشتر ...](https://apigee.com/about/blog/technology/restful-api-design-tips-versioning)
- پیامهای پاسخ (Response) باید خودتوضیحدهنده باشند، بهطوریکه گیرنده بتواند بهراحتی مفهوم آنها را درک کند. یک پیام خطای مناسب ممکن است شبیه به این باشد:
```json
{
"code": 1234,
"message": "Something bad happened",
"description": "More details"
}
```
یا برای خطاهای اعتبارسنجی:
```json
{
"code": 2314,
"message": "Validation Failed",
"errors": [
{
"code": 1233,
"field": "email",
"message": "Invalid email"
},
{
"code": 1234,
"field": "password",
"message": "No password provided"
}
]
}
```
_چرا:_
> توسعهدهندگان در زمانهای بحرانی که در حال عیبیابی و حل مشکلات پس از انتشار برنامههایی که با استفاده از APIهای شما ساختهاند و در دست کاربران قرار گرفتهاند، به خطاهای خوب و خوشطراحیشده وابسته هستند.
_توجه: پیامهای استثنا مربوط به امنیت را تا حد ممکن عمومی و ساده نگه دارید. به عنوان مثال، به جای اینکه بنویسید «رمز عبور اشتباه است»، میتوانید پیام «نام کاربری یا رمز عبور نامعتبر است» را بازگردانید. این کار باعث میشود که بهطور ناخودآگاه به کاربر اطلاع ندهید که نام کاربری درست است و تنها رمز عبور اشتباه است._
- از این کدهای وضعیت (status codes) برای ارسال همراه با پاسخهای خود استفاده کنید تا مشخص کنید آیا **همه چیز درست انجام شده است یا خیر**، آیا **کلاینت اشتباهی انجام داده** یا **مشکل از API بوده است**.
_کدام یک:_
> پاسخ `200 OK` نشاندهنده موفقیت برای درخواستهای `GET`, `PUT` یا `POST` است.
> کد `201 Created` برای زمانی است که یک نمونه جدید ایجاد میشود. ایجاد یک نمونه جدید با استفاده از متد `POST` کد وضعیت `201` را برمیگرداند.
> پاسخ `204 No Content` نشاندهنده موفقیت است، اما محتوایی برای ارسال در پاسخ وجود ندارد. از آن در زمانی استفاده کنید که عملیات `DELETE` با موفقیت انجام شده است.
> پاسخ `304 Not Modified` برای به حداقل رساندن انتقال اطلاعات زمانی که گیرنده قبلاً نسخههای کششده را دارد، استفاده میشود.
> کد `400 Bad Request` برای زمانی است که درخواست پردازش نشده است، زیرا سرور نمیتواند بفهمد که مشتری چه چیزی درخواست کرده است.
> کد `401 Unauthorized` برای زمانی است که درخواست فاقد اعتبارنامههای معتبر است و باید با اعتبارنامههای مورد نیاز دوباره ارسال شود.
> کد `403 Forbidden` به این معنی است که سرور درخواست را فهمیده است، اما از اعطای مجوز خودداری میکند.
> کد `404 Not Found` نشان میدهد که منبع درخواستی پیدا نشده است.
> کد `500 Internal Server Error` نشان میدهد که درخواست معتبر است، اما سرور به دلیل برخی شرایط غیرمنتظره نمیتواند آن را انجام دهد.
_چرا:_
> بیشتر ارائهدهندگان API از تعداد کمی از کدهای وضعیت HTTP استفاده میکنند. برای مثال، API سرویس Google GData تنها از ۱۰ کد وضعیت، Netflix از ۹ کد، و Digg تنها از ۸ کد وضعیت استفاده میکنند. البته، این پاسخها معمولاً شامل بدنهای هستند که اطلاعات بیشتری را ارائه میدهد. در کل، بیش از ۷۰ کد وضعیت HTTP وجود دارد. اما اکثر توسعهدهندگان همه این ۷۰ کد را به خاطر ندارند.بنابراین، اگر شما کدهای وضعیتی را انتخاب کنید که خیلی رایج نیستند، توسعهدهندگان مجبور میشوند به جای ادامه کار روی برنامه خود، وقتشان را صرف جستجو در ویکیپدیا کنند تا متوجه شوند شما چه چیزی را سعی دارید به آنها بگویید. [توضیحات بیشتر ...](https://apigee.com/about/blog/technology/restful-api-design-what-about-errors)
- تعداد کل منابع/دیتا را در پاسخ (response) خود اعلام کنید.
- پارامترهای `limit` و `offset` را بپذیرید.
- مقدار دادهای که یک منبع در پاسخ ارائه میدهد نیز باید مورد توجه قرار گیرد. مصرفکننده API همیشه به تمام اطلاعات مربوط به یک منبع نیاز ندارد. از پارامتر fields استفاده کنید که لیستی از فیلدها را به صورت جدا شده با کاما دریافت میکند تا مشخص کند کدام فیلدها در پاسخ گنجانده شوند:
```
GET /students?fields=id,name,age,class
```
- پشتیبانی از صفحهبندی (pagination)، فیلتر کردن (filtering) و مرتبسازی (sorting) نیازی نیست از ابتدا برای همه منابع (resourceها) فعال باشد. منابعی که این قابلیت را دارند، باید به طور مستند (از طریق Document) مشخص شوند.
<a name="api-security"></a>
### 9.2 امنیت ایپیآی/API security
این موارد برخی از بهترین روشهای امنیتی پایه هستند:
- از احراز هویت پایه (Basic Authentication) استفاده نکنید، مگر اینکه از یک اتصال امن (HTTPS) استفاده کنید. توکنهای احراز هویت نباید در URL منتقل شوند: `GET /users/123?token=asdf....`
_چرا:_
> زیرا توکن یا شناسه کاربری و رمز عبور به صورت متن ساده (clear text) در شبکه ارسال میشوند (اگرچه به صورت Base64 کدگذاری شده است، اما Base64 یک کدگذاری برگشتپذیر است). بنابراین، روش احراز هویت پایه ایمن نیست. [توضیحات بیشتر ...](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication)
- توکنها باید با استفاده از هدر Authorization در هر درخواست منتقل شوند: `Authorization: Bearer xxxxxx, Extra yyyyy`.
- کدهای Authorization باید مدتزمان کوتاهی معتبر باشند.
- هرگونه درخواست بدون TLS را رد کنید. به درخواستهای HTTP (بدون TSL) پاسخ ندهید تا از تبادل دادههای ناامن جلوگیری شود. اگر پاسخ میدهید، از کد وضعیت `403 Forbidden` استفاده کنید.
- استفاده از نرخ محدودیت (Rate Limiting) را در نظر بگیرید.
_چرا:_
> برای حفاظت از API در برابر تهدیدات باتهایی که ممکن است هزاران بار در ساعت API شما را فراخوانی میکنند. باید محدودیت نرخ (rate limit) را از همان مراحل اولیه پیادهسازی مد نظر قرار دهید.
- تنظیم مناسب هدرهای HTTP میتواند به ایمنسازی برنامه وب شما کمک کند. [توضیحات بیشتر ...](https://github.com/helmetjs/helmet)
- API شما باید دادههای دریافتشده را به فرم استانداردشان تبدیل کند یا آنها را رد کند. در صورت وجود دادههای نادرست یا ناقص، کد وضعیت 400 Bad Request را همراه با جزئیات خطا در پاسخ بازگردانید.
- تمام دادههای مبادلهشده با REST API باید توسط خود API اعتبارسنجی شوند.
- JSON خود را سریالایز (Serialize) کنید.
_چرا:_
> یکی از نگرانیهای اصلی کار با JSON، جلوگیری از اجرای کدهای جاوااسکریپت دلخواه از remote در مرورگر است... یا اگر از node.js در سمت سرور استفاده میکنید. بسیار مهم و حیاتی است که از یک سریالایزر JSON مناسب استفاده کنید تا دادههای ورودی کاربر به درستی کدگذاری شوند و از اجرای دادههای ورودی کاربر در مرورگر جلوگیری شود.
- نوع محتوا (Content-Type) را اعتبارسنجی کنید و بیشتر از `application/*json` (هدر Content-Type) استفاده کنید.
_چرا:_
> به عنوان مثال، پذیرش نوع `application/x-www-form-urlencoded` به مهاجم اجازه میدهد یک فرم ایجاد کند و یک درخواست POST ساده ارسال کند. سرور هرگز نباید نوع محتوا (Content-Type) را فرض کند. عدم وجود هدر Content-Type یا وجود یک Content-Type غیرمنتظره باید منجر به رد محتوا توسط سرور با یک پاسخ `4XX` شود.
- پروژه API Security Checklist را بررسی کنید. [توضیحات بیشتر ...](https://github.com/shieldfy/API-Security-Checklist)
<a name="api-documentation"></a>
### 9.3 مستندسازی ایپیآی/API documentation
- بخش `API Reference` را در [README.md template](./README.sample.md) برای API پر کنید.
- روشهای احراز هویت API را با یک نمونه کد توضیح دهید.
- ساختار URL (فقط path بدون root URL) را به همراه نوع درخواست (Method) شرح دهید.
برای هر Endpoint، موارد زیر را توضیح دهید:
- اگر پارامترهای URL وجود دارند، آنها را مطابق با نام ذکر شده در بخش URL مشخص کنید:
```
Required: id=[integer]
Optional: photo_id=[alphanumeric]
```
- اگر نوع درخواست POST است، نمونههای کاربردی ارائه دهید. قوانین پارامترهای URL در اینجا نیز اعمال میشوند. این بخش را به دو دسته اختیاری و الزامی تقسیم کنید.
- پاسخ موفقیتآمیز (Success Response)، کد وضعیت (Status Code) چه باید باشد و آیا دادهای در پاسخ بازگردانده میشود یا خیر؟ این اطلاعات زمانی مفید است که کاربران نیاز دارند بدانند چه چیزی از پاسخ دریافت خواهند کرد:
```
Code: 200
Content: { id : 12 }
```
- پاسخ خطا (Error Response)، بیشتر endpointها ممکن است به روشهای مختلفی شکست بخورند. از دسترسی غیرمجاز گرفته تا پارامترهای اشتباه و غیره. تمامی این موارد باید در این بخش لیست شوند. ممکن است تکراری به نظر برسد، اما از ایجاد فرضیات جلوگیری میکند. به عنوان مثال:
```json
{
"code": 401,
"message": "Authentication failed",
"description": "Invalid username or password"
}
```
- از ابزارهای طراحی API استفاده کنید؛ ابزارهای متنباز زیادی برای مستندسازی خوب وجود دارند، مانند [API Blueprint](https://apiblueprint.org/) و [Swagger](https://swagger.io/).
<a name="a11y"></a>
## 10. دسترسپذیری/Accessibility ([a11y](https://www.a11yproject.com/))
<p align="right">
<img src="/images/accessibility.png" alt="Accessibility" width="128" height="128">
</p>
### 10.1 پیادهسازی روشهای دسترسیپذیری
برای اطمینان از حفظ سطح مشخصی از دسترسیپذیری، **از ابتدای پروژه خود** مراحل زیر را انجام دهید:
_چرا:_
> محتوای وب [بهطور پیشفرض دسترسیپذیر](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML)است. ما این ویژگی را زمانی به خطر میاندازیم که امکانات پیچیده ایجاد میکنیم. در نظر گرفتن دسترسیپذیری از ابتدا بسیار آسانتر از بازپیادهسازی این ویژگیها در آینده است تا تأثیر آن را کاهش دهیم.
- با استفاده از ابزارهایی مانند [lighthouse](https://developers.google.com/web/tools/lighthouse#devtools) برای [دسترسیپذیری](https://web.dev/lighthouse-accessibility/) یا افزونه [axe DevTools](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)برنامهریزیهایی را جهت انجام ممیزیهای منظم انجام دهید. بر اساس نیازهای پروژه خود، بر روی یک امتیاز حداقلی توافق کنید. امتیازدهی در این ابزارها بر اساس [ارزیابی تأثیر کاربر در axe](https://github.com/dequelabs/axe-core/blob/develop/doc/rule-descriptions.md#wcag-21-level-a--aa-rules) میباشد.
> **نکته:** [برخی بررسیهای مهم](https://web.dev/lighthouse-accessibility/#additional-items-to-manually-check) باید بهصورت دستی انجام شوند، مانند ترتیب منطقی تبها. ابزارهای فوق این موارد را به عنوان تستهای دستی یا راهنماییشده در کنار نتایج خودکار فهرست میکنند. در axe باید نتایج خودکار خود را ذخیره کنید تا این موارد را مشاهده کنید.
- یک Linter مرتبط با دسترسپذیری نصب کنید:
- در ریاکت: [eslint-plugin-jsx-a11y](https://www.npmjs.com/package/eslint-plugin-jsx-a11y)
- در انگولار: [Angular Codelyzer](https://github.com/mgechev/codelyzer)
- در ویو: [eslint-plugin-vuejs-accessibility](https://github.com/vue-a11y/eslint-plugin-vuejs-accessibility)
_چرا:_
> یک لینتر بهطور خودکار بررسی میکند که سطح پایهای از دسترسیپذیری در پروژه شما رعایت شده است و راهاندازی آن نسبتاً آسان است.
- با استفاده از [axe-core](https://www.youtube.com/watch?v=-n5Ul7WPc3Y&list=PLMlWGnpsViOMt24a-Y_dybv68H-kj6Un6&t=1649s) یا ابزارهای مشابه، تستهای دسترسیپذیری را راهاندازی و اجرا کنید.
- اگر از Storybook استفاده میکنید، این [راهنما](https://storybook.js.org/blog/accessibility-testing-with-storybook/) را دنبال کنید.
_چرا:_
> گنجاندن بررسیهای دسترسپذیری در تستها به شما کمک میکند تا هر تغییری که بر دسترسپذیری پروژه و امتیاز ممیزی تأثیر میگذارد، شناسایی کنید.
- از یک دیزان سیستم دسترسیپذیر مانند [React Spectrum](https://react-spectrum.adobe.com/react-spectrum/) یا [Material Design](https://material.io/design) استفاده کنید.
_چرا:_
> این کامپوننتها به صورت پیشفرض از سطح بالایی از دسترسپذیری برخوردار هستند.
### 10.2 برخی از قوانین پایه دسترسپذیری که باید به پروژه خود اضافه کنید:
- اطمینان حاصل کنید که نام لینکها دسترسپذیر هستند. از aria-label برای توصیف لینکها استفاده کنید.
_چرا:_
> لینکهایی که غیرقابل دسترس میباشند، برای دسترسپذیری موانعی ایجاد میکنند.
- اطمینان حاصل کنید که لیستها بهدرستی ساختاربندی شده باشند و عناصر لیست به صورت معنایی استفاده شدهاند.
_چرا:_
> لیستها باید دارای عناصر والد و عناصر فرزند باشند تا معتبر باشند. صفحهخوانها (Screen Readers) به کاربران اطلاع میدهند که وقتی به یک لیست میرسند، لیست شامل چند آیتم است.
- اطمینان حاصل کنید که ترتیب سرفصلها (Heading Order) از نظر معنایی صحیح است.
_چرا:_
> سرفصلها ساختار صفحه را منتقل میکنند. هنگامی که به درستی اعمال شوند، پیمایش صفحه آسانتر میشود.
- اطمینان حاصل کنید که عناصر متنی دارای کنتراست کافی با پسزمینهی صفحه هستند.
_چرا:_
> برخی افراد با بینایی کم، کنتراست پایین را تجربه میکنند؛ به این معنی که تفاوت زیادی بین مناطق روشن و تاریک وجود ندارد. همه چیز تقریباً با همان میزان روشنایی ظاهر میشود، که تشخیص خطوط، حاشیهها، لبهها و جزئیات را دشوار میکند. متنی که از نظر روشنایی بسیار نزدیک به پسزمینه باشد، ممکن است سخت خوانده شود.
- برای تصاویر، متن جایگزین (Alt Text) ارائه دهید.
_چرا:_
> صفحهخوانها نمیتوانند تصاویر را به کلماتی تبدیل کنند که برای کاربر خوانده شود، حتی اگر تصویر فقط شامل متن باشد. در نتیجه، ضروری است که تصاویر دارای متن جایگزین کوتاه و توصیفی باشند تا کاربران صفحهخوان بهوضوح محتوای تصویر و هدف آن را درک کنند.
قوانین بیشتری درباره دسترسپذیری را میتوانید [اینجا](https://dequeuniversity.com/rules/axe) پیدا کنید.
<a name="licensing"></a>
## 11. مجوزدهی/Licensing
<p align="right">
<img src="/images/licensing.png" alt="Licensing" width="135" height="135">
</p>
اطمینان حاصل کنید که از منابعی استفاده میکنید که حق استفاده از آنها را دارید. اگر از کتابخانهها استفاده میکنید، به مجوزهای MIT، Apache یا BSD توجه کنید، اما اگر این کتابخانهها را تغییر میدهید، حتماً جزئیات مجوز را بررسی کنید. استفاده از تصاویر و ویدئوهای دارای حق کپیرایت (Copyrighted) ممکن است مشکلات قانونی ایجاد کند.
---
منابع:
[RisingStack Engineering](https://blog.risingstack.com/),
[Mozilla Developer Network](https://developer.mozilla.org/),
[Heroku Dev Center](https://devcenter.heroku.com),
[Airbnb/javascript](https://github.com/airbnb/javascript),
[Atlassian Git tutorials](https://www.atlassian.com/git/tutorials),
[Apigee](https://apigee.com/about/blog),
[Wishtack](https://blog.wishtack.com)
Icons by [icons8](https://icons8.com/)
================================================
FILE: README-it.md
================================================
[中文版](./README-zh.md)
| [日本語版](./README-ja.md)
| [한국어](./README-ko.md)
| [English](./README.md)
| [Русский](./README-ru.md)
| [Português](./README-pt-BR.md)
| [Persian/فارسی](./README-ir.md)
[<img src="./images/elsewhen-logo.png" width="180" height="180">](https://www.elsewhen.com/)
# Linee guida di un progetto · [](http://makeapullrequest.com)
> Se sviluppare un nuovo progetto è per voi come rotolarsi in un campo erboso, il mantenimento
> è un potenziale oscuro incubo per qualcun altro.
> Ecco un elenco delle linee guida che abbiamo trovato, scritto e raccolto che (pensiamo), possano
> realmente ben funzionare con la maggior parte dei progetti qui a [elsewhen](https://www.elsewhen.com).
> Se volete condividere una pratica ottimale, o pensate che qualcuna di queste linee guida debba essere rimossa, [fatecelo sapere](http://makeapullrequest.com).
<hr>
- [Git](#git)
- [Alcune regole di Git](#some-git-rules)
- [Flusso di lavoro di Git](#git-workflow)
- [Scrivere efficaci messaggi di commit](#writing-good-commit-messages)
- [Documentazione](#documentation)
- [Ambienti](#environments)
- [Ambienti di sviluppo consistenti:](#consistent-dev-environments)
- [Dipendenze consistenti](#consistent-dependencies)
- [Dipendenze](#dependencies)
- [Eseguire test](#testing)
- [Denominazioni e strutture](#structure-and-naming)
- [Stile di codice](#code-style)
- [Alcune linee guida di stile di codice](#some-code-style-guidelines)
- [Applicare uno standard nello stile di codice](#enforcing-code-style-standards)
- [Logging](#logging)
- [API](#api)
- [Progettazione API](#api-design)
- [Sicurezza API](#api-security)
- [Documentazione API](#api-documentation)
- [Accessibilità](#a11y)
- [Gestione Licenze](#licensing)
<a name="git"></a>
## 1. Git

<a name="some-git-rules"></a>
### Alcune regole di Git
Ecco un insieme di regole da tenere a mente:
- Eseguire il lavoro in un _branch_ di funzionalità.
_Perchè:_
> In questo modo tutto il lavoro viene fatto in isolamento su _branch_ dedicato piuttosto che nel principale. Questo consente di sottomettere delle richieste _pull_ multiple senza creare confusione. E' possibile iterare senza inquinare il _branch master_ con codice potenzialmente instabile e/o non completato. [maggiori informazioni...](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow)
- Creare _branch_ da `develop`
_Perchè:_
> In questo modo ci si può assicurare che il codice in _master_ possa essere quasi sempre compilato senza problemi, e che possa essere principalmente usato direttamente per i rilasci (potrebbe essere una esagerazione per alcuni progetti).
- Mai eseguire _push_ nei _branch_ `develop` o `master`. Eseguire una richiesta _pull_
_Perchè:_
> Notifica i membri della squadra che una funzionalità è stata completata. Consente anche una facile revisione tra i propri pari del codice e una discussione della funzionalità proposta sui _forum_ dedicati.
- Aggiornare il _branch_ `develop` locale ed eseguire un _rebase_ interattivo prima di proporre la propria funzionalità ed eseguire una richiesta _pull_.
_Perchè:_
> L'azione di _rebase_ integrerà nei _branch_ richiesti (`master` o `develop`) i commit fatti localmente all'inizio della storicizzazione senza creare un _merge commit_ (assumendo che non ci siano conflitti). Il risultato è una buona e pulita storicizzazione. [maggiori informazioni ...](https://www.atlassian.com/git/tutorials/merging-vs-rebasing)
- Risolvere conflitti potenziali durante l'azione di _rebase_ e prima di eseguire una richiesta _pull_.
- Eliminare i _branch_ di funzionalità locali e remoti dopo l'integrazione.
_Perchè:_
> Il non farlo sporcherà il proprio elenco di _branch_ con _branch_ morti. Assicura che si possa integrare il _branch_ in (`master` o `develop`) una volta sola. I _branch_ di funzionalità dovrebbero esistere solo se il lavoro è ancora in corso.
- Prima di eseguire una richiesta _pull_, assicurarsi che il proprio _branch_ di funzionalità venga compilato con successo e superi tutti i test (compresi quelli di stile di codice).
_Perchè:_
> Si sta per aggiungere il proprio codice a un _branch_ stabile. Se i test nel proprio _branch_ di funzionalità falliscono, ci sarà un alta probabilità che la compilazione nel _branch_ di destinazione fallirà anch'essa. Inoltre, occorre applicare un controllo di stile di codice prima di eseguire una richiesta _pull_. Aggiunge leggibilità e riduce le possibilità che correzioni di formattazione vengano mescolate con le vere modifiche.
- Usare [questo file `.gitignore`](./.gitignore).
_Perchè:_
> Ha già un elenco di file di sistema che non dovrebbero essere inviati assieme al proprio codice in un _repository_ remoto. Inoltre esclude cartelle e file di impostazione per la maggior parte degli editor utilizzati, così come molte delle più comuni cartelle di dipendenze.
- Proteggere i propri _branch_ di `develop` e `master`.
_Perchè:_
> Protegge i propri _branch_ pronti per la produzione dal ricevere modifiche inattese e irreversibili, maggiori informazioni... [Github](https://help.github.com/articles/about-protected-branches/), [Bitbucket](https://confluence.atlassian.com/bitbucketserver/using-branch-permissions-776639807.html) e [GitLab](https://docs.gitlab.com/ee/user/project/protected_branches.html)
<a name="git-workflow"></a>
### 1.2 Flusso di lavoro di Git
Per la maggior parte delle ragioni sopra esposte usiamo il flusso di lavoro [Feature-branch-workflow](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow) con [Rebase Interattivo](https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing) e alcuni elementi di [Gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows#gitflow-workflow) (denominazioni e avere un _branch_ di sviluppo). I passi principali sono i seguenti:
- Per un nuovo progetto, inizializzare un _repository_ git nella directory di progetto. **Per le funzionalità/modifiche successive questo passo dovrebbe essere ignorato**.
```sh
cd <directory di progetto>
git init
```
- Eseguire il _checkout_ di un nuovo _branch_ di funzionalità/risoluzione _bug_.
```sh
git checkout -b <nome branch>
```
- Eseguire le modifiche.
```sh
git add <file1> <file2> ...
git commit
```
_Perchè:_
> `git add <file1> <file2> ... ` - si dovrebbero aggiungere solo file che costituiscono una piccola e coerente modifica.
> `git commit` lancerà un editor che consente di separare il soggetto dal corpo.
> Si legga di più in merito nella _sezione 1.3_.
_Suggerimento:_
> Si può invece usare `git add -p`, che potrebbe dare la possibilità di rivedere tutte le modifiche introdotte una ad una e decidere se includerle nel _commit_ oppure no.
- Sincronizzare con il _repository_ remoto per ottenere modifiche che altrimenti si sarebbero perso.
```sh
git checkout develop
git pull
```
_Perchè:_
> Fornisce la possibilità di gestire i conflitti sulla propria macchina mentre si esegue la successiva azione di _rebase_ invece che creare una richiesta _pull_ che contiene conflitti.
- Aggiornare il proprio _branch_ di funzionalità con le ultime modifiche da `develop` tramite _rebase_ interattivo.
```sh
git checkout <nome branch>
git rebase -i --autosquash develop
```
_Perchè:_
> Si può usare `--autosquash` per comprimere tutti i propri _commit_ in un _commit_ singolo. Nessuno vuole molti _commit_ per una singola funzionalità nel _branch_ di sviluppo. [maggiori informazioni...](https://robots.thoughtbot.com/autosquashing-git-commits)
- Se non si hanno conflitti saltare questo passo. Se si hanno conflitti, [risolverli](https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/) e continuate l'azione di _rebase._
```sh
git add <file1> <file2> ...
git rebase --continue
```
- Eseguire l'azione di _push_ del proprio _branch_. L'azione di _rebase_ modificherà la storicizzazione, quindi si dovrà usare `-f` per forzare le modifiche nel _branch_ remoto. Se qualcun altro sta lavorando sul proprio _branch_, usare l'opzione meno distruttiva `--force-with-lease`.
```sh
git push -f
```
_Perchè:_
> Quando si esegue una azione di _rebase_, si sta modificando la storicizzazione del proprio _branch_ di funzionalità. Come risultato, Git respingerà i normali `git push`. Dovrà invece essere usata l'opzione `-f` o `--force flag`. [maggiori informazioni...](https://developer.atlassian.com/blog/2015/04/force-with-lease/)
- Eseguire una richiesta _pull_.
- La richiesta _pull_ verrà accettata, incorporata e chiusa da un revisore.
- Rimuovere il proprio _branch_ locale di funzionalità se completato.
```sh
git branch -d <branchname>
```
rimuovere tutti i rami che non sono più nel _repository_ remoto
```sh
git fetch -p && for branch in `git branch -vv --no-color | grep ': gone]' | awk '{print $1}'`; do git branch -D $branch; done
```
<a name="writing-good-commit-messages"></a>
### 1.3 Scrivere messaggi di _commit_ efficaci
Avere buone linee guida per la creazione di _commit_ e osservarle rende molto più facile lavorare con Git e collaborare con altri. Ecco alcune regole di massima ([sorgente](https://chris.beams.io/posts/git-commit/#seven-rules)):
- Separare l'oggetto dal corpo con una riga vuota tra i due.
_Perchè:_
> Git è in grado di considerare la prima riga del proprio messaggio di _commit_ come sommario. In effetti se si esegue `git shortlog` invece che `git log`, si vedrà un lungo elenco di messaggi di _commit_, che contengono l'identificativo del _commit_ e il solo sommario.
- Limitare la riga dell'oggetto a 50 caratteri e la lunghezza della riga nel corpo a massimo 72 caratteri.
_Perchè:_
> I _commit_ dovrebbero essere più dettagliati e specifici possibile, non è il posto per essere prolissi. [maggiori informazioni...](https://medium.com/@preslavrachev/what-s-with-the-50-72-rule-8a906f61f09c)
- Maiuscole nella riga di oggetto.
- Non terminare la riga dell'oggetto con un punto.
- Usare [il modo imperativo](https://it.wikipedia.org/wiki/Imperativo) nella riga dell'oggetto.
_Perchè:_
> Invece che scrivere messaggi che dicono cosa ha fatto chi ha eseguito il _commit_, è meglio considerare questi messaggi come istruzioni per quello che si andrà a fare dopo che il _commit_ è stato applicato nel _repository_. [maggiori informazioni...](https://news.ycombinator.com/item?id=2079612)
- Usare il corpo per spiegare **cosa** e **perchè** invece di **come**.
<a name="documentation"></a>
## 2. Documentazione

- Usare questo [modello](./README.sample.md) per `README.md`. Si è liberi di aggiungere sezioni non trattate.
- Per progetti con più di un _repository_, fornire collegamenti agli stessi nei rispettivi file `README.md`.
- Mantenere aggiornato `README.md` mano a mano che il progetto evolve.
- Commentare il proprio codice. Cercate di rendere il più chiaro possibile il proprio intendimento con ogni sezione principale.
- Se esiste una discussione aperta su github o stackoverflow riguardo al codice o all'approccio che si sta usando, includere il collegamento nel proprio commento.
- Non usare commenti come scusa per cattivo codice, mantenere il proprio codice pulito.
- Non usare codice pulito come scusa per non commentarlo del tutto.
- Mantenere i commenti rilevanti mano a mano che il proprio codice evolve.
<a name="environments"></a>
## 3. Ambienti

- Definire ambienti `development` (sviluppo), `test` (collaudo) e `production` (produzione) separati se serve.
_Perchè:_
> Dati diversi, _token_, API, porte ecc... potrebbero essere necessari in ambienti diversi. Si potrebbe volere un ambiente di sviluppo (`development`) isolato che chiami delle "false" API che forniscono dati predeterminati, rendendo i test sia manuali che automatici molto più facili. Oppure si portrebbe voler abilitare Google Analytics solo in ambiente di produzione (`production`) e così via. [maggiori informazioni...](https://stackoverflow.com/questions/8332333/node-js-setting-up-environment-specific-configs-to-be-used-with-everyauth)
- Caricare le proprie configurazioni di sviluppo specifiche da variabili di ambiente e non aggiungerle mai alla base di codice come costanti, [guardare questo esempio](./config.sample.js).
_Perchè:_
> Si hanno _token_, password e altre preziose informazioni lì dentro. La propria configurazione dovrebbe essere correttamente separata dalle logiche interne dell'app come se la base di codice potesse essere resa pubblica in qualsiasi momento.
_Come:_
> Usare file `.env` per conservare le proprie variabili e aggiungerli a `.gitignore` per escluderli. Eseguire un _commit_ di un `.env.esempio` che serva come guida per gli sviluppatori. Per la produzione, si dovrebbero comunque impostare le proprie variabili nel modo standard. [maggiori informazioni](https://medium.com/@rafaelvidaurre/managing-environment-variables-in-node-js-2cb45a55195f)
- E' raccomandato che si validino le variabili di ambiente prima che la propria app venga lanciata. [Guardare questo esempio](./configWithTest.sample.js) che usa `joi` per validare i valori passati.
_Perchè:_
> Potrebbe risparmiare ad altri ore passate a risolvere problemi.
<a name="consistent-dev-environments"></a>
### 3.1 Ambienti di sviluppo consistenti:
- Impostare la propria versione di node in `engines` in `package.json`.
_Perchè:_
> Consente agli altri di sapere su quale versione di node il progetto lavora. [maggiori informazioni...](https://docs.npmjs.com/files/package.json#engines)
- Inoltre usare `nvm` e creare un file `.nvmrc` in radice del proprio progetto. Non dimenticare di citarlo nella documentazione.
_Perchè:_
> Chiunque usi `nvm` può semplicemente usare `nvm use` per passare alla versione di node adatta. [maggiori informazioni...](https://github.com/creationix/nvm)
- E' una buona idea impostare uno script di preinstallazione che verifichi le versioni di node e npm.
_Perchè:_
> Alcune dipendenze potrebbero fallire quando installate da versioni più nuove di npm.
- Usare immagini Docker se possibile.
_Perchè:_
> Può fornire un ambiente consistente lungo tutto il flusso di lavoro. Senza tanto bisogno di armeggiare con dipendenze o configurazioni. [maggiori informazioni...](https://hackernoon.com/how-to-dockerize-a-node-js-application-4fbab45a0c19)
- Usare moduli locali invece di quelli installati globalmente.
_Perchè:_
> Consente di condividere il proprio equipaggiamento con il collega invece di aspettarsi che li abbia installati globalmente sul proprio sistema.
<a name="consistent-dependencies"></a>
### 3.2 Consistenza nella dipendenze:\*\*\*\*
- Assicurarsi che i membri della propria squadra abbiano le stesse esatte dipendenze.
_Perchè:_
> Perchè si vuole che il codice si comporti come atteso e in modo identico in qualsiasi macchina di sviluppo [maggiori informazioni...](https://kostasbariotis.com/consistent-dependencies-across-teams/)
_Come:_
> Usare `package-lock.json` su `npm@5` o superiori
_Non ho npm@5:_
> Come alternativa si potrebbe usare `Yarn` e assicurarsi di citarlo nel `README.md`. I propri file di lock e `package.json` dovrebbero avere le stesse versioni dopo ogni aggiornamento di dipendenze. [maggiori informazioni...](https://yarnpkg.com/en/)
_Non mi piace il nome `Yarn`:_
> Peccato. Per versioni più vecchie di `npm`, usare `—save --save-exact` quando si installa una nuova dipendenza e creare `npm-shrinkwrap.json` prima della pubblicazione. [maggiori informazioni...](https://docs.npmjs.com/files/package-locks)
<a name="dependencies"></a>
## 4. Dipendenze

- Tenere traccia dei propri pacchetti attualmente disponibili: es. `npm ls --depth=0`. [maggiori informazioni...](https://docs.npmjs.com/cli/ls)
- Verificare se qualcuno dei propri pacchetti è diventato irrilevante o inutilizzato: `depcheck`. [maggiori informazioni...](https://www.npmjs.com/package/depcheck)
_Perchè:_
> Si potrebbe includere una libreria inutilizzata nel proprio codice aumentando la dimensione del pacchetto di produzione. Cercare le dipendenze inutilizzate e sbarazzarsene.
- Prima di usare una dipendenza, verificare le statistiche degli scaricamenti per verificare se sia ampiamente utilizzata dalla comunità: `npm-stat`. [maggiori informazioni...](https://npm-stat.com/)
_Perchè:_
> Più utilizzi in genere significa più collaboratori, il che in genere significa migliore manutenzione, e la conseguenza è che i _bug_ vengono scoperti e corretti più velocemente.
- Prima di usare una dipendenza, verificare se ha una frequenza di rilascio di versione buona, matura e con un ampio numero di manutentori: `npm view async`. [maggiori informazioni...](https://docs.npmjs.com/cli/view)
_Perchè:_
> Avere un gran numero di sottomissioni di codice da parte dei collaboratori non è così efficace se non ci sono manutentori che incorporano le correzioni e _patch_ con sufficiente velocità.
- Se è necessaria una dipendenza poco conosciuta, discuterne con la squadra prima di usarla.
- Assicurarsi sempre che la propria app funzioni con le ultime versioni delle proprie dipendenze senza errori: `npm outdated`. [maggiori informazioni...](https://docs.npmjs.com/cli/outdated)
_Perchè:_
> Gli aggiornamenti delle dipendenze talvolta contengono modifiche che rompono l'app. Verificate sempre le loro note di rilascio quando vengono messi a disposizione gli aggiornamenti. Aggiornare le proprie dipendenze una ad una, il che facilita la risoluzione dei problemi se qualcosa dovesse andare storto. Usare uno strumento tipo [npm-check-updates](https://github.com/tjunnone/npm-check-updates).
- Verificare se il pacchetto abbia delle vulnerabilità di sicurezza note con [Snyk](https://snyk.io/test?utm_source=risingstack_blog) as esempio.
<a name="testing"></a>
## 5. Eseguire Test

- Se necessario dotarsi di un ambiente in modalità `test`.
_Perchè:_
> Sebbene qualche volta il test _end-to-end_ in ambiente di produzione possa sembrare sufficiente, ci sono alcune eccezioni: un esempio è che si potrebbe non voler abilitare informazioni analitiche (in modalità produzione) e inquinare il cruscotto di qualcuno con dati di test. Un altro esempio è che la propria API potrebbero avere dei parametri di limite in produzione e bloccare le chiamate di test dopo un certo numero di richieste.
- Posizionare i propri file di test vicino ai moduli testati usando la convenzione nominale `*.test.js` o `*.spec.js`, tipo `nomeModulo.spec.js`.
_Perchè:_
> Non si vorrà rovistare all'interno di una struttura di directory per trovare una unità di test. [maggiori informazioni...](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc)
- Inserire i propri file di test addizionali in una cartella di test separata per evitare confusione.
_Perchè:_
> Alcuni file di test non sono particolarmente legati a specifici file di implementazione. Si dovranno inserire in una cartella che sia facile da trovare per gli altri sviluppatori: `__test__`. Questo nome: `__test__` è anche uno standard ora e viene scelto dalla maggior parte delle infrastrutture di test di Javascript.
- Scrivere codice che si possa testare, evitare effetti collaterali, eliminare effetti collaterali, scrivere funzioni pure
_Perchè:_
> Si vuole testare una logica di _business_ come unità separate. Si deve "minimizzare l'impatto della casualità e dei processi non deterministici sulla affidabilità del proprio codice". [maggiori informazioni...](https://medium.com/javascript-scene/tdd-the-rite-way-53c9b46f45e3)
> Una funzione pura è una funzione che ritorna sempre lo stesso risultato dato lo stesso input. Al contrario una funzione impura è quella che potrebbe avere effetti collaterali o dipende da condizioni esterne per produrre un valore. Il che la rende meno prevedibile. [maggiori informazioni...](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc)
- Usare un verificatore di tipo statico
_Perchè:_
> Talvolta si potrebbe aver bisogno di un verificatore di tipo statico. Porta un certo grado di affidabilità al proprio codice. [maggiori informazioni...](https://medium.freecodecamp.org/why-use-static-types-in-javascript-part-1-8382da1e0adb)
- Eseguire i test localmente prima di eseguire una richiesta _pull_ nel _branch_ di sviluppo (`develop`).
_Perchè:_
> Non si vuole essere quello che ha causato una fallita compilazione in un _branch_ pronto per la produzione. Eseguire i propri test prima della propria azione di _rebase_ e prima di inviare il proprio _branch_ di funzionalità in un _repository_ remoto.
- Documentare i propri test includendo istruzioni nelle sezioni rilevanti del proprio file `README.md`.
_Perchè:_
> E' una nota utile che si lascia a disposizione degli altri sviluppatori o esperti DevOps o chiunque sia abbastanza fortunato da lavorare al codice.
<a name="structure-and-naming"></a>
## 6. Struttura e Assegnazione dei Nomi

- Organizzare i propri file attorno a funzionalità / pagine / componenti, non ruoli. Inoltre inserire i propri file di test vicino alla loro implementazione.
**Cattivo**
```
.
├── controllers
| ├── product.js
| └── user.js
├── models
| ├── product.js
| └── user.js
```
**Buono**
```
.****
├── product
| ├── index.js
| ├── product.js
| └── product.test.js
├── user
| ├── index.js
| ├── user.js
| └── user.test.js
```
_Perchè:_
> Invece di un lungo elenco di file, si creeranno piccoli moduli che incapsulano una responsabilità compresi i test relativi e così via. E' molto più facile scorrerli e le cose si possono trovare a colpo d'occhio.
- Inserire i propri file di test aggiuntivi in cartelle di test separate per evitare confusione.
_Perchè:_
> Costituisce un risparmio di tempo per gli altri sviluppatori o esperti DevOps nella propria squadra.
- Usare una cartella `./config` e non creare file di configurazione diversi per i diversi ambienti.
_Perchè:_
> Quando si divide un file di configurazione per diversi scopi (database, API eccetera) metterli in una cartella con un nome molto riconoscibile tipo `config`. Ricordarsi di non generare diversi file di configurazione per diversi ambienti.
> Non sarebbe possibile scalarli in modo pulito, mano a mano che sono creati più sviluppi per l'app e saranno necessari nuovi nomi di ambiente per ogni distribuzione.
> I valori da usare nei file di configurazione dovrebbero essere forniti da variabili di ambiente. [maggiori informazioni...](https://medium.com/@fedorHK/no-config-b3f1171eecd5)
- Inserire i propri script in una cartella `./scripts` . Compresi gli script `bash` e `node`.
_Perchè:_
> E' molto probabile che si finisca per avere più di uno script, per la produzione, lo sviluppo, alimentazione di database, sincronizzazione di database eccetera.
- Piazzare il risultato delle compilazioni in una cartella `./build`. Aggiungere `build/` a `.gitignore`.
_Perchè:_
> Denominarla a piacimento, anche `dist` va bene, ma assicurarsi di mantenere consistenza con la propria squadra. Quello che finisce lì per la maggior parte è generato (assemblato, compilato, soggetto a _transpiling_), o ivi spostato. Anche i componenti della propria squadra dovrebbero essere in grado di generarlo, quindi non ha senso portare questi dati nel _repository_ remoto. A meno che non lo si voglia specificatamente.
<a name="code-style"></a>
## 7. Stile di codice

<a name="code-style-check"></a>
### 7.1 Alcune linee guida sullo stile di codice
- Usare una sintassi di secondo stadio (_stage-2_) o superiore (_modern_) di Javascript per i propri nuovi progetti. Per quelli vecchi restare consistenti con la sintassi esistente a meno che si intenda modernizzare il progetto.
_Perchè:_
> E' una scelta personale. Qui usiamo programmi per il _transpiling_ per trarre vantaggio dalla nuova sintassi, è probabile che _stage-2_ diventi alla fine parte delle specifiche con poche minori revisioni.
- Includere verifiche di stile di codice nel proprio processo di compilazione.
_Perchè:_
> Rompere la compilazione è un modo per imporre uno stile di codice. Evita di prenderlo sotto gamba. Farlo sia per il codice della parte _client_ che per quella _server_. [maggiori informazioni...](https://www.robinwieruch.de/react-eslint-webpack-babel/)
- Usare [ESLint - Pluggable JavaScript linter](http://eslint.org/) per imporre lo stile di codice.
_Perchè:_
> Semplicemente noi preferiamo `eslint`, ma gli altri non sono obbligati. Supporta più regole e la possibilità di configurarle nonchè di aggiungerne di personalizzate.
- Usiamo [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript) per JavaScript, [maggiori informazioni](https://www.gitbook.com/book/duk/airbnb-javascript-guidelines/details). Usare lo stile di codice javascript richiesto dal proprio progetto o dalla propria squadra.
- Usiamo [Flow type style check rules for ESLint](https://github.com/gajus/eslint-plugin-flowtype) quando usiamo [FlowType](https://flow.org/).
_Perchè:_
> _Flow_ introduce poca sintassi, la quale deve seguire certe regole di stile di codice e possono essere verificate.
- Usare `.eslintignore` per escludere file o cartelle dalle verifiche di stile di codice.
_Perchè:_
> Non si deve inquinare il proprio codice con commenti `eslint-disable` ogni volta che si deve escludere un paio di file dalla verifica di stile.
- Rimuovere tutti i propri commenti di disabilitazione di `eslint` prima di eseguire una richiesta _pull_.
_Perchè:_
> E' normale disabilitare verifiche di stile mentre si lavora a un blocco di codice per focalizzarsi più sulla logica. Ricordarsi solo di rimuovere quei commenti `eslint-disable` e seguire le regole.
- A seconda della dimensione dell'attività usare commenti `//TODO:` oppure aprire un ticket.
_Perchè:_
> In questo modo si può ricordare agli altri e a se stessi di una piccola attività (tipo rifattorizzare una funzione o aggiornare un commento). Per attività più complesse usare `//TODO(#3456)` che viene imposto da una regola di _lint_ e il numero è quello di un ticket aperto.
- Commentare sempre il codice e mantenere i commenti in linea con le modifiche fino ad ora apportate. Eliminare i blocchi di codice commentati.
_Perchè:_
> Il proprio codice dovrebbe essere il più leggibile possibile, ci si dovrebbe sbarazzare di ogni distrazione. Se si rifattorizza una funzione non commentare la vecchia ma eliminarla.
- Evitare commenti, log e attribuzione di nominativi irrilevanti o divertenti.
_Perchè:_
> Anche se il proprio processo di compilazione potrebbe (dovrebbe) sbarazzarsi di questi, talvolta il proprio codice sorgente potrebbe essere affidato ad altra ditta/cliente e potrebbero non trovarli così divertenti.
- Rendere i propri nomi ricercabili con distinzioni significative ed evitare abbreviazioni di nomi. Per le funzioni usare nomi lunghi e descrittivi. Un nome di funzione dovrebbe essere un verbo o una frase verbale, e deve comunicare le proprie intenzioni.
_Perchè:_
> Rende la lettura del codice sorgente più naturale.
- Organizzare le proprie funzioni in un file a seconda della regole di discesa. Funzioni di alto livello dovrebbero essere in testa e quelle di basso livello più in basso.
_Perchè:_
> Rende la lettura del codice sorgente più naturale.
<a name="enforcing-code-style-standards"></a>
### 7.2 Imporre standard di stile di codice
- Usare un file [.editorconfig](http://editorconfig.org/) che aiuta gli sviluppatori a definire e mantenere stili di codice consistente tra i diversi editor e IDE usati nel progetto.
_Perchè:_
> Il progetto EditorConfig consiste in un file che descrive un formato per definire stili di codice e una collezione di plugin che consentono agli editor di leggere il file di formato e di aderire agli stili definiti. I file EditorConfig sono facilmente leggibili e funzionano bene con sistemi di controllo di versione.
- Fare in modo di essere notificati dal proprio editor circa gli errori di stile di codice. Usare [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) e [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) con la propria configurazione esistente di ESLint. [maggiori informazioni...](https://github.com/prettier/eslint-config-prettier#installation)
- Considerare l'uso di _Git hooks_.
_Perchè:_
> Accrescono notevolmente la produttività di uno sviluppatore. Fare modifiche, eseguire _commit_ e portarle sugli ambienti di _staging_ o produzione senza paura di rompere la compilazione. [maggiori informazioni...](http://githooks.com/)
- Usare _Prettier_ con un _hook_ prima del _commit_.
_Perchè:_
> Sebbene `prettier` per se stesso possa essere molto potente, non è molto produttivo se eseguito semplicemente come una attività npm a se stante ogni volta per formattare il codice. Ecco dove `lint-staged` (e `husky`) entrano in gioco. Maggiori informazioni su come configurare `lint-staged` [qui](https://github.com/okonet/lint-staged#configuration) e `husky` [qui](https://github.com/typicode/husky).
<a name="logging"></a>
## 8. Logging

- Evitare log su console lato client in produzione.
_Perchè:_
> Anche se il processo di compilazione possa (dovrebbe) sbarazzarsene, assicurarsi che il proprio verificatore di stile di codice avvisi rispetto a log su console lasciati nel codice.
- Produrre dei log di produzione leggibili. Idealmente utilizzare librerie di _logging_ in produzione (tipo [winston](https://github.com/winstonjs/winston) o [node-bunyan](https://github.com/trentm/node-bunyan)).
_Perchè:_
> Rende l'identificazione dei problemi molto meno sgradevole con colorazioni, marcature temporali, registrazioni a un file oltre a quelle su console, anche la registrazione su file che ruota giornalmente. [maggiori informazioni...](https://blog.risingstack.com/node-js-logging-tutorial/)
<a name="api"></a>
## 9. API
<a name="api-design"></a>

### 9.1 Progettazione API
_Perchè:_
> Si cerca di imporre lo sviluppo di interfacce _RESTful_ ben costruite, che possono essere consumate dai membri della squadra e i _client_ in modo semplice e consistente.
_Perchè:_
> La mancanza di consistenza e semplicità può accrescere enormemente i costi di integrazione e mantenimento. Ecco perchè la progettazione API è inclusa in questo documento.
- Noi seguiamo per la maggior parte una progettazione orientata alle risorse. Ci sono tre fattori principali: risorse, collezioni e URL.
- Una risorsa ha dati, viene annidata e ci sono metodi che operano su di essa.
- Un gruppo di risorse è chiamata collezione.
- Un URL identifica la posizione _online_ di risorse o collezioni.
_Perchè:_
> Questa è una progettazione ben nota agli sviluppatori (i principali consumatori della propria API). A parte la leggibilità e la facilità d'uso, consente di scrivere librerie generiche e connettori senza neppure sapere come sia fatta l'API stessa.
- Usare il _kebab-case_ per gli URL.
- Usare il _camelCase_ per parametri in _query string_ o campi che rappresentano una risorsa.
- Usare il _kebab-case_ al plurale per nomi di risorse negli URL.
- Usare sempre la forma plurale dei nomi per denominare un url che punta a una collezione: `/utenti`.
_Perchè:_
> Fondamentalmente risulta meglio leggibile e rende gli URL consistenti. [maggiori informazioni...](https://apigee.com/about/blog/technology/restful-api-design-plural-nouns-and-concrete-names)
- Nel codice sorgente convertire le forme plurali in variabili e le proprietà con un suffisso `List`.
_Perchè_:
> La forma plurale va bene negli URL ma nel codice sorgente è troppo debole e incline a errori.
- Usare sempre un concetto al singolare che parte da una collezione e finisce con un identificatore:
```
/studenti/245743
/aeroporti/kjfk
```
- Evitare URL tipo questo:
```
GET /blogs/:blogId/posts/:postId/sommario
```
_Perchè:_
> Non punta a una risorsa ma a una proprietà. Si possono passare le proprietà come parametro per ridurre la propria risposta.
- Escludere i verbi dai propri URL di risorse.
_Perchè:_
> Se si usa un verbo per ogni operazione su una risorsa presto si avrà una enorme lista di URL e un modello non consistente che lo rende difficile da imparare per gli sviluppatori. Inoltre usiamo i verbi per altri scopi.
- Usare verbi per non-risorse. In questo caso, la propria API non ritorna alcuna risorsa; viceversa si esegue una operazione e si ritorna il risultato. Queste **non sono** operazioni CRUD (creazione, lettura, aggiornamento e cancellazione):
```
/traduci?testo=Ciao
```
_Perchè:_
> Per le operazioni CRUD usiamo i metodi HTTP su URL su risorse o collezioni. I verbi di cui si sta parlando sono in realtà `Controllers`. In genere non ne sviluppano molti di questi. [maggiori informazioni...](https://byrondover.github.io/post/restful-api-guidelines/#controller)
- Il corpo della richiesta o il tipo di risposta è JSON pertanto seguire la forma `camelCase` per i nomi di proprietà per mantenere una consistenza.
_Perchè:_
> Queste sono linee guida per un progetto Javascript, dove il linguaggio di programmazione per generare ed elaborare JSON si assume sia JavaScript.
- Anche se una risorsa rappresenta un concetto al singolare, simile a una istanza di un oggetto o un record di database, non si dovrebbe usare il `nome_tabella` per un nome di risorsa e il `nome_colonna` per una proprietà.
_Perchè:_
> L'intendimento è di esporre risorse, non i dettagli dello schema del proprio database.
- Ancora una volta, usare solo nomi nei propri URL quando si denominano le proprie risorse non si cerchi di spiegarne la loro funzionalità.
_Perchè:_
> Usare nomi solamente nei propri URL di risorsa, evitare URL che finiscono con `/aggiungiNuovoUtente` o `/aggiornaUtente`. Evitare inoltre di inviare operazioni su risorse come parametro.
- Esprimere le funzionalità CRUD usando i metodi HTTP:
_Come:_
> `GET`: Per ottenere la rappresentazione di una risorsa.
> `POST`: Per creare nuove risorse e sotto risorse.
> `PUT`: Per aggiornare risorse esistenti.
> `PATCH`: Per aggiornare risorse esistenti. Aggiorna solo i campi che sono stati forniti lasciando gli altri invariati.
> `DELETE`: Per eliminare risorse esistenti.
- Per risorse annidate, usare la relazione tra loro nell'URL. Ad esempio usare `id` per collegare un dipendente a una ditta.
_Perchè:_
> Questo è il modo naturale per rendere le risorse esplorabili.
_Come:_
> `GET /scuole/2/studenti `, dovrebbe ottenere la lista di tutti gli studenti dalla scuola 2.
> `GET /scuole/2/studenti/31`, dovrebbe ottenere i dettagli dello studente 31, che appartiene alla scuola 2.
> `DELETE /scuole/2/studenti/31` , dovrebbe eliminare lo studente 31, che appartiene alla scuola 2.
> `PUT /scuole/2/studenti/31` , dovrebbe aggiornare le info sullo studente 31, usare PUT solo su URL che rappresentano risorse, non collezioni.
> `POST /scuole` , dovrebbe creare una nuova scuola e ritornare i dettagli della nuova scuola creata. Usare POST su URL che rappresentano una collezione.
- Usare un semplice numero ordinale per una versione con un prefisso `v` (v1, v2). Spostare tutto alla sinistra nell'URL in modo che abbia l'ordine di identificazione maggiore:
```
http://api.domain.com/v1/scuole/3/studenti
```
_Perchè:_
> Quando le proprie API sono disponibili per terze parti, l'aggiornamento di API con alcune modifiche incompatibili con le versioni precedenti faranno sì che i prodotti o servizi che si basano su di esse non funzioneranno più. L'utilizzo di un controllo di versione nel proprio URL previene questa eventualità. [maggiori informazioni...](https://apigee.com/about/blog/technology/restful-api-design-tips-versioning)
- I messaggi di risposta devono essere auto descrittivi. Un buon messaggio di errore in risposta potrebbe essere tipo questo:
```json
{
"code": 1234,
"message": "E' successo qualcosa di brutto",
"description": "Maggiori dettagli"
}
```
oppure per errori di validazione:
```json
{
"code": 2314,
"message": "Validazione fallita",
"errors": [
{
"code": 1233,
"field": "email",
"message": "Email non valida"
},
{
"code": 1234,
"field": "password",
"message": "Nessuna password fornita"
}
]
}
```
_Perchè:_
> Gli sviluppatori fanno affidamento su messaggi di errore ben concepiti quando stanno cercando di risolvere il problema dopo che l'applicazione che hanno costruito usando la vostra API viene utilizzata dai loro utenti.
- \_Nota: Mantenere i messaggi di eccezione di sicurezza più generici possibile. Ad esempio invece di 'password errata' utilizzare 'utente o password errati' in modo che l'utente non possa dedurre che il nome utente sia corretto e la sola password sia sbagliata.
- Usare questi codici di stato per inviare i propri codici di risposta per descrivere che **tutto ha funzionato**,
che l'**app _client_ ha fatto qualcosa di errato** oppure l'**API ha fatto qualcosa di errato**.
_Quali sono:_
> `200 OK` la risposta rappresenta un successo per le richieste `GET`, `PUT` o `POST`.
> `201 Created` quando viene creata una nuova istanza. Quando si crea una nuova istanza usando un metodo `POST` ritornare il codice di stato `201`.
> `204 No Content` la risposta rappresenta un successo ma non c'è contenuto da inviare con la risposta. Usarlo quando una operazione di `DELETE` ha successo.
> `304 Not Modified` la risposta è per minimizzare la info da trasferire quando il ricevente ne ha già una rappresentazione in cache.
> `400 Bad Request` quando la richiesta non viene elaborata, come se il _server_ non potesse capire cosa gli è stato chiesto.
> `401 Unauthorized` quando la richiesta è priva di credenziali valide e dovrebbe essere riproposta con le credenziali richieste.
> `403 Forbidden` il _server_ ha compreso la richiesta ma si rifiuta di autorizzarla.
> `404 Not Found` la risorsa richiesta non esiste.
> `500 Internal *Server* Error` la richiesta è valida, ma il _server_ non può esaudirla a causa di condizioni inaspettate.
_Perchè:_
> La maggior parte dei fornitori di API usa un piccolo sottoinsieme di codici di stato HTTP. Ad esempio l'api di Google GData usa solo 10 codici di stato, Netflix ne usa 9 e Digg solo 8. Naturalmente queste risposte contengono un corpo con info aggiuntive. Ci sono oltre 70 codici di stato HTTP. In ogni caso la maggior parte degli sviluppatori non li ha tutti memorizzati. Quindi quando si scelgono codici di stato che non sono molto comuni si obbligheranno gli sviluppatori ad abbandonare lo sviluppo della propria applicazione per consultare wikipedia per scoprire cosa gli si sta cercando di dire. [maggiori informazioni...](https://apigee.com/about/blog/technology/restful-api-design-what-about-errors)
- Fornire il numero totale di risorse nella risposta.
- Accettare parametri di `limit` (limite) e `offset` (scostamento).
- Il volume di dati che la risorsa espone dovrebbe essere tenuto in considerazione. Il consumatore dell'API non sempre necessita della piena rappresentazione di una risorsa. Usare un parametro di specifica di campi che riceve un elenco separato da virgola di campi che devono essere inclusi nella risposta:
```
GET /studente?campi=id,nome,eta,classe
```
- Paginazioni, filtri, e ordinamento non devono essere supportati dall'inizio per tutte le risorse. Documentare quali risorse offrono filtro e ordinamento.
<a name="api-security"></a>
### 9.2 Sicurezza delle API
Ci sono alcune migliori pratiche consigliate
- Non usare l'autenticazione basica a meno di avere una connessione sicura (HTTPS). I _token_ di autenticazione non devono essere trasmessi nell'URL: `GET /users/123?*token*=asdf....`
_Perchè:_
> I _token_ o identificativo utente e password sono passati attraverso la rete in chiaro (codificato in base64, che è una codifica reversibile), lo schema di autenticazione basica non è sicuro. [maggiori informazioni...](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication)
- I _token_ devono essere trasmessi usando l'intestazione di autorizzazione per ogni richiesta: `Authorization: Bearer xxxxxx, Extra yyyyy`.
- I codici di autorizzazione dovrebbero avere vita breve.
- Rifiutare qualsiasi richiesta non-TLS non rispondendo a qualunque richiesta HTTP per evitare scambio di dati non sicuro. Rispondere a queste richieste HTTP con `403 Forbidden`.
- Considerare l'adozione di limiti di utilizzo
_Perchè:_
> Per proteggere le proprie API da minacce di bot che chiamano l'API migliaia di volte all'ora. Si consideri l'implementazione di limiti di utilizzo ai primi stadi dello sviluppo.
- L'appropriata impostazione delle intestazioni HTTP può aiutare a isolare e mettere in sicurezza la propria applicazione web. [maggiori informazioni...](https://github.com/helmetjs/helmet)
- La propria API dovrebbe convertire i dati ricevuti nella loro forma canonica o rifiutarli. Ritornare un `400 Bad Request` con dettagli circa gli errori per dati non corretti o mancanti.
- Tutti i dati scambiati con API REST devono essere validati dall'API.
- Serializzare il proprio JSON.
_Perchè:_
> Una preoccupazione chiave con i codificatori JSON è la prevenzione dell'esecuzione di codice Javascript arbitrario all'interno del browser oppure, se si sta usando node.js, sul _server_. E' vitale utilizzare un appropriato serializzatore JSON per codificare correttamente i dati forniti dall'utente per prevenire l'esecuzione di input fornito dall'utente nel browser.
- Validare il Content-type e per lo più utilizzare l'intestazione Content-Type `application/*json`.
_Perchè:_
> Ad esempio accettando il tipo mime `application/x-www-form-urlencoded` si consente a un attaccante di creare un form e scatenare una semplice richiesta POST. Il _server_ non dovrebbe mai dare per scontato il Content-Type. La mancanza di una intestazione Content-Type oppure una non attesa dovrebbe risultare in un rifiuto del contenuto da parte del _server_ con una risposta `4XX`.
- Verificare il "Progetto per la Lista delle Verifiche per la Sicurezza delle API". [maggiori informazioni...](https://github.com/shieldfy/API-Security-Checklist)
<a name="api-documentation"></a>
### 9.3 Documentazione delle API
- Riempire la sezione `API Reference` in [README.md template](./README.sample.md) per l'API.
- Descrivere i metodi di autenticazione dell'API con un esempio di codice.
- Spiegare la struttura dell'URL (solo il percorso, non la radice dell'URL) includendo il tipo di richiesta (metodo).
Per ogni _endpoint_ spiegare:
- I parametri per l'URL, se esistono, specificarli in base al nome citato nella sezione URL:
```
Richiesto: id=[intero]
Opzionale: photo_id=[alfanumerico]
```
- Se il tipo di richiesta è POST, fornire esempi funzionanti. Le regole per i parametri di URL si applicano anche qui. Separare le sezioni tra Richiesto e Opzionale.
- Risposte di successo. Quale dovrebbe essere il codice di stato e ci sono anche dei dati da ritornare? Questo è utile quando a qualcuno occorre sapere cosa dovrebbero aspettarsi i propri callback:
```
Code: 200
Content: { id : 12 }
```
- Risposte di errore, la maggior parte degli _endpoint_ hanno molti modi per fallire. Da accesso non autorizzato a parametri errati ecc. Tutto ciò dovrebbe essere documentato qui. Può sembrare ripetitivo, ma aiuta ad evitare che vengano fatte delle assunzioni. Ad esempio
```json
{
"code": 401,
"message": "Autenticazione fallita",
"description": "Nome utente o password errati"
}
```
- Usare strumenti di progettazione di API. Ce ne sono molti _open source_ con buona documentazione tipo [API Blueprint](https://apiblueprint.org/) e [Swagger](https://swagger.io/).
<a name="a11y"></a>
## [Accessibiltà](https://www.a11yproject.com/)

### 10.1 Mettere a punto metodi di accessibilità
Prendere le seguenti misure **all'inizio del proprio progetto** per assicurare che un livello di accessibilità sia intenzionalmente sostenuto:
_Perchè:_
> Il contenuto Web è [accessibile in modalità predefinita](https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML).Questo concetto viene compromesso quando si costruiscono funzionalità complesse. E' molto più facile ridurre questo impatto tenendo in considerazione l'accessibilità dall'inizio invece che reimplementare queste funzionalità successivamente.
- Disporsi per eseguire revisioni regolari usando [lighthouse](https://developers.google.com/web/tools/lighthouse#devtools) [accessibility](https://web.dev/lighthouse-accessibility/) o l'[estensione di DevTools axe](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US). Condividere un punteggio minimo in base alle proprie specifiche di progetto. Il punteggio per entrambi gli strumenti è basato su [usare l'impatto di valutazione utente di axe](https://github.com/dequelabs/axe-core/blob/develop/doc/rule-descriptions.md#wcag-21-level-a--aa-rules).
> **Nota:** [alcune importanti verifiche](https://web.dev/lighthouse-accessibility/#additional-items-to-manually-check) devono essere fatte manualmente, es. ordine logico delle tabulazioni. Gli strumenti qui sopra elencano questi test manuali/guidati assieme ai risultati automatizzati. Con axe si devono salvare i propri risultati automatizzati per vedere questi.
- Installare un _linter a11y_:
- React: [eslint-plugin-jsx-a11y](https://www.npmjs.com/package/eslint-plugin-jsx-a11y)
- Angular: [Angular Codelyzer](https://github.com/mgechev/codelyzer)
- Vue: [eslint-plugin-vuejs-accessibility](https://github.com/vue-a11y/eslint-plugin-vuejs-accessibility)
_Perchè:_
> Un linter verificherà automaticamente che un livello base di accessibilità sia raggiunto dal proprio progetto ed è relativamente facile da impostare.
- Impostare e usare test a11y usando [axe-core](https://www.youtube.com/watch?v=-n5Ul7WPc3Y&list=PLMlWGnpsViOMt24a-Y_dybv68H-kj6Un6&t=1649s) o simili.
- Se si sta usando storybook, fare [questo](https://storybook.js.org/blog/accessibility-testing-with-storybook/).
_Perchè:_
> Includere verifiche a11y nei propri test aiuterà a catturare qualsiasi modifica che abbia impatto sull'accessibilità del propri progetti e il proprio punteggio di revisione.
- Considerare l'uso di un sistema di progettazione accessibile tipo [React Spectrum](https://react-spectrum.adobe.com/react-spectrum/) o [Material Design](https://material.io/design).
_Perchè:_
> Questi componenti sono altamente accessibili fuori dalla scatola.
### 10.2 Alcune regole di accessibilità di base da aggiungere al proprio progetto:
- Assicurarsi che i nomi dei link siano accessibili. Usare aria-label per descrivere i collegamenti.
_Perchè:_
> Elementi di collegamento inaccessibili pongono barriere all'accessibilità.
- Assicurarsi che le liste siano strutturate correttamente e gli elementi della lista siano usati in modo semantico.
_Perchè:_
> Le liste devono avere elementi sia genitori che figli affinchè siano valide. I lettori di schermo informano gli utenti quando trovano una lista e quanti elementi ci sono in una lista.
- Assicurarsi che l'ordine delle intestazioni sia semanticamente corretto.
_Perchè:_
> Le intestazioni veicolano la struttura della pagina. Quando applicate correttamente rendono la pagina più facile da navigare.
- Assicurarsi che gli elementi di testo abbiano contrasto sufficiente rispetto allo sfondo della pagina.
_Perchè:_
> Alcune persone con impedimenti alla vista soffrono di un basso contrasto, il che vuol dire che non riescono a distinguere aree molto chiare o molto scure. Tutto tende ad apparire quasi della stessa luninosità, il che rende difficile distinguere strutture, cornici, margini e dettagli. Un testo troppo vicino in luminosità allo sfondo può essere difficile da leggere.
- Fornire testo alternativo per le immagini.
_Perchè:_
> I lettori di schermo non hanno modo di tradurre un'immagine in parole che vengono lette all'utente, anche se l'immagine è composta solo da testo. Di conseguenza, è necessario che le immagini abbiano un testo alternativo (l'attributo `alt`) descrittivo in modo che gli utenti del lettore di schermo comprendano chiaramente i contenuti e lo scopo dell'immagine.
Altre regole di accessibilità possono essere trovate [qui](https://dequeuniversity.com/rules/axe).
## 11. Gestione Licenza

Assicurarsi di usare risorse per la quali si possiede il diritto di utilizzo. Se si utilizzano librerie, ricordarsi di cercare se licenza MIT, Apache o BSD ma se vengono modificate, verificare anche i dettagli della licenza. Le immagini o i video sottoposti a copyright potrebbero causare problemi legali.
---
Sorgenti:
[RisingStack Engineering](https://blog.risingstack.com/),
[Mozilla Developer Network](https://developer.mozilla.org/),
[Heroku Dev Center](https://devcenter.heroku.com),
[Airbnb/javascript](https://github.com/airbnb/javascript),
[Atlassian Git tutorials](https://www.atlassian.com/git/tutorials),
[Apigee](https://apigee.com/about/blog),
[Wishtack](https://blog.wishtack.com)
Icone di [icons8](https://icons8.com/)
================================================
FILE: README-ja.md
================================================
[中文版](./README-zh.md)
| [ENGLISH](./README.md)
| [한국어](./README-ko.md)
| [РУССКИЙ](./README-ru.md)
| [Português](./README-pt-BR.md)
| [Persian/فارسی](./README-ir.md)
[<img src="./images/elsewhen-logo.png" width="180" height="180">](https://www.elsewhen.com/)
# プロジェクトガイドライン[](http://makeapullrequest.com)
> 開発中の新たなプロジェクトは草原のようですが、メンテナンスは誰にとっても悪夢になります。
> ここには私たちが見つけ記載し、集め考えたガイドラインがあります。 このガイドラインはほとんどの[elsewhen](https://www.elsewhen.com)の JavaScript のプロジェクトで機能しています。
> もしもベストプラクティスを我々と共有したかったり、このガイドラインの項目は削除した方が良いと思ったら[気軽に私たちに報告してください](http://makeapullrequest.com)。
- [Git](#git)
- [Git のルール](#some-git-rules)
- [Git workflow](#git-workflow)
- [良いコミットメッセージの書き方](#writing-good-commit-messages)
- [ドキュメント](#documentation)
- [開発環境](#environments)
- [統一された開発環境](#consistent-dev-environments)
- [一貫した依存性](#consistent-dependencies)
- [依存関係](#dependencies)
- [テスト](#testing)
- [プロジェクトの構造と名前付け](#structure-and-naming)
- [コードスタイル](#code-style)
- [コードスタイルガイドライン](#code-style-check)
- [標準的なコードスタイルの強制](#enforcing-code-style-standards)
- [ログ](#logging)
- [API](#api)
- [API デザイン](#api-design)
- [API セキュリティ](#api-security)
- [API ドキュメント](#api-documentation)
- [ライセンス](#licensing)
<a name="git"></a>
## 1. Git

<a name="some-git-rules"></a>
### 1.1 Git のルール
いくつかの Git のルールを覚えておきましょう。
- feature ブランチで作業しましょう。
_Why:_
> 全作業がメインブランチではなくて独立した作業専用のブランチで完結するからです。そうすることによって混乱をきたすことなく複数のプルリクエストを作成することができます。作業途中のコードや不安定なコードを master ブランチを気にすることなく繰り返し作れます。[もっと読む...](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow)
- `develop`ブランチからブランチを切りましょう
_Why:_
> こうすることで master のコードを問題なくビルドできることができ、master はリリース用にほとんどそのまま利用できます。(プロジェクトによってはやりすぎかもしれません。)
- `develop`と`master`ブランチに直接 Push するのはやめましょう。プルリクエストを作成しましょう。
_Why:_
> `develop`と`master`ブランチが更新されるということはチームメンバーにその機能を実装し終わったと伝えることと同義です。直接 Push さえしなければ、コードレビューや新たな機能の議論がしやすくなります。
- feature ブランチを Push してプルリクエストを作成する前にローカルの`develop` ブランチを最新にして、feature ブランチをインタラクティブリベースしましょう。
_Why:_
> リベースはブランチ(`master`か`develop`か)をマージします。また local に作ったコミットをマージコミットを作成せずに Git のヒストリーのトップに並べ替えます。コンフリクトがなければ。そうすることで綺麗で素晴らしいヒストリーが残ります。[もっと読む...](https://www.atlassian.com/git/tutorials/merging-vs-rebasing)
- リベースする間やプルリクエストを作る前にコンフリクトを解消しましょう。
- マージした後のブランチは local、remote 共に削除しましょう。
_Why:_
> 不要になったブランチをが含まれることで自身 local のブランチのリストが乱雑になるでしょう。またマージする時にのみ一回だけブランチ(`master`か`develop`)に戻ることを保証します。feature ブランチは作業中だけ存在すべきです。
- プルリクエストを前に、feature ブランチのビルドの成功を確認して全てのテストを通しましょう。(コードのスタイルも含めて確認しましょう。)
_Why:_
> 安定的なコードを追加しようとする時、もし feature ブランチのテストが失敗したとすると、最終的なマージ後のテストも失敗する可能性が高いです。加えてプルリクエストを作成する前に、スタイルチェックを行う必要があります。スタイルチェックを行うことで可読性が上がり、実際のコードと一緒にフォーマットによる修正を減らすことに繋がります。
- [こちらの](./.gitignore)`.gitignore`ファイルを使いましょう。
_Why:_
> この.gitignore ファイルには remote のリポジトリに含めたくないシステムファイルのリストを列挙しています。またユーザーが多くの人が使うエディタ用のフォルダやファイル(依存フォルダも同じように)も含めてます。
- `develop`と`master`ブランチを保護しましょう。
_Why:_
> プロダクションに備えているブランチに予期しない破壊的なコミットが Push されることを防ぎます。
<a name="git-workflow"></a>
### 1.2 Git workflow
上記の理由のために、私達は[Feature-branch-workflow](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow)と[Interactive Rebasing](https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing)、[Gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows#gitflow-workflow) の要素のいくつか(名前付と develop ブランチを持つこと)を使います。主なステップは以下の通りです。
- 新しいプロジェクトにとっては初期の git の設定。**features/changes ブランチの作成は の次のステップなので無視しましょう。**
```sh
cd <project directory>
git init
```
- feature/bug-fix ブランチを作成する。
```sh
git checkout -b <branchname>
```
- コードを変更する。
```sh
git add
git commit -a
```
_Why:_
> `git commit -a`を使うと本文から主題を切り離して始めることができます。詳しくは*section 1.3*を読みましょう。
- 取り込まれていない変更を取得する為にリモートのリボジトリと同期しましょう。
```sh
git checkout develop
git pull
```
_Why:_
> こうすることでコンフリクトを含めながらプルリクエストを作成するのではなくてリベース(のちに)しつつ、コンフリクトに対処できる可能性が高まります。
- feature ブランチにインタラクティブリベースをすることで常に develop の変更を取り込みましょう。
```sh
git checkout <branchname>
git rebase -i --autosquash develop
```
_Why:_
> --autosquash は全てのコミットを一つにまとめることができます。一つの feature に対して複数のコミットがある状態は望ましくありません。[もっと読む...](https://robots.thoughtbot.com/autosquashing-git-commits)
- もしコンフリクトしてなかったらこの章は飛ばして大丈夫です。ただしもしコンフリクトが起きてたら[解決しましょう](https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/)。そしてリベースを続けましょう。
```sh
git add <file1> <file2> ...
git rebase --continue
```
- 自分のブランチを Push しましょう。リベースはヒストリーを改変しますので、リモートに Push する際は`-f` のオプションをつけて Push する必要があります。もし他の人が同じブランチで作業をしていたらより破壊的でない`--force-with-lease`を使いましょう。
```sh
git push -f
```
_Why:_
> リベースをすると、作業ブランチのコミットヒストリーを変えることになります。結果として Git に普通の`git push`は拒否されるので代わりに -f や--force フラグを使えば大丈夫です。[もっと読む...](https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/)
- プルリクエストを作りましょう。
- プルリクエストが受け入れられたら、レビュワーによってマージされて課題が閉じられます。
- マージが完了したらローカルのブランチを消しましょう。
```sh
git branch -d <branchname>
```
必要のないリモートブランチを全て削除するコマンド。
```sh
git fetch -p && for branch in `git branch -vv | grep ': gone]' | awk '{print $1}'`; do git branch -D $branch; done
```
<a name="writing-good-commit-messages"></a>
### 1.3 良いコミットメッセージの書き方
コミットを作成して維持するための良い指針を持つと、Git をうまく使うことができ他の開発者との共同作業をとても簡単にします。ここにいくつかの経験則があります。([ソース](https://chris.beams.io/posts/git-commit/#seven-rules))
- 本文を改行することで主題と切り離しましょう。
_Why:_
> Git は最初の行をそのコミットのサマリとして区別します。実際`git log`の代わりに`git shortlog`を使うと、コミット ID とサマリーのみで構成される長いコミットメッセージのリストを見ることができます。
- 主題は 50 文字以内、本文を含めても 72 文字以内に制限しましょう。
_why_
> コミットはできる限りきめ細やかで完結あるべきで、コミットメッセージを冗長にすることは避けましょう。[詳しく読む](https://medium.com/@preslavrachev/what-s-with-the-50-72-rule-8a906f61f09c)
- 主題の先頭は大文字にしましょう。
- ピリオドで終わるのをやめましょう。
- 主題部分では[命令法](https://en.wikipedia.org/wiki/Imperative_mood) を使いましょう。
_Why:_
> コミッタが何を行ったかわかりやすいメッセージを書きましょう。コミットがマージされた後にそのコミットが何をしたのかをうまく説明できるように考えるといいでしょう。[もっと読む...](https://news.ycombinator.com/item?id=2079612)
- 本文は **How** ではなくて **What** と **Why**を説明しましょう。
<a name="documentation"></a>
## 2. ドキュメント

- こちらの[テンプレート](./README.sample.md)を使って`README.md`を作成しましょう。空白のセクションがあっても気にしなくても大丈夫です。
- 一つ以上の Git リポジトリがあるようなプロジェクトでは、各々の`README.md`ファイルをリンクさせてあげましょう。
- プロジェクトの成長に合わせて`README.md`の情報を最新に保ちましょう。
- コードにはコメントを書きましょう。その際には自分の意図をできる限り簡潔に書くように心がけましょう。
- もしコードや試みているアプローチについて github や stackoverllow でオープンな議論があれば、そのリンクもコメントに含めましょう。
- ダメなコードに対する言い訳を書くのはやめましょう。コードを綺麗に保ちましょう。
- 綺麗なコードを全くコメントがないことに対する言い訳にするのはやめましょう。
- コードの成長に合わせてコメントを最新に保ちましょう。
<a name="environments"></a>
## 3. 開発環境

- 必要なら`development`, `test` と`production`の環境を分けて定義しましょう。
_Why:_
> データやトークンや API、ポートなど環境によって必要とされるものは様々です。。。テストの自動化と手動のテストを簡単にさせるために、`development`モードは予測可能なデータを返すフェイクの API が欲しいかもしれません。もしくは Google Analytics は`production`でだけ有効にしたかったり様々でしょう。[もっと読む...](https://stackoverflow.com/questions/8332333/node-js-setting-up-environment-specific-configs-to-be-used-with-everyauth)
- 環境別の Config ファイルを環境毎に適用するようにして、コードベースに定数として決して書き込まないでください。[サンプル](./config.sample.js)
_Why:_
> トークン、パスワードなど様々な重要な個人情報を持っています。 その情報はコードベースがいつ公開されてもいいように、コードベースとは切り離さないといけません。
_How:_
> `.env`ファイルを情報を保持するために使いましょう。そのファイルは`.gitignore`に加えて、Git リポジトリからは除外されるようにします。その代わりに`.env.example`のようなサンプルを他の開発者向けのガイドとしてコミットしておきましょう。production 環境用に、環境設定は標準的なやり方で設定するようにしましょう。
> [もっと読む...](https://medium.com/@rafaelvidaurre/managing-environment-variables-in-node-js-2cb45a55195f)
- アプリケーションを開始する前に環境変数を validate することをオススメします。[サンプルを参照](./configWithTest.sample.js) 変数を Validate するために`joi`を使っています。
_Why:_
> トラブルシューティングに費やす時間を節約することに繋がります。
<a name="consistent-dev-environments"></a>
### 3.1 統一された開発環境
- node のバージョンを`package.json`の中の`engines`に設定しましょう。
_Why:_
> どのバージョンの node をそのプロジェクトで使うべきかを示すことができます。[もっと読む...](https://docs.npmjs.com/files/package.json#engines)
- さらに`nvm` を使って`.nvmrc`をプロジェクトルートに作成しましょう。ドキュメント内に記述を残すことを忘れないようにしましょう。
_Why:_
> `nvm`を使う人は誰でも誰でも`nvm use`を使うことで node のバージョンを切り替えることができます。[もっと読む...](https://github.com/creationix/nvm)
- `preinstall`スクリプトを使って node と npm のバージョンを確かめるのがいいでしょう。
_Why:_
> npm の新たなバージョンでインストールすると依存関係のライブラリが失敗することがあります。
- できるならば Docker イメージを使いましょう。
_Why:_
> Docker イメージは全てのワークフローを跨いで同じ環境を提供してくれます。依存関係やコンフィグファイルに悩む必要があまりないようになります。[もっと読む...](https://hackernoon.com/how-to-dockerize-a-node-js-application-4fbab45a0c19)
- グローバルのモジュールを使うのではなくローカルのモジュールを使いましょう。
_Why:_
> 同僚が特定のモジュールを彼らのマシンにすでにインストールしていることを期待するのではなく、使うライブラリは共有できるようにしておきましょう。
<a name="consistent-dependencies"></a>
### 3.2 一貫した依存関係
- チームメンバーが同じ依存関係を取得できることを確認しましょう。
_Why:_
> コードにはどんな開発マシンでも同じ挙動をしてほしいからです。[もっと読む...](https://medium.com/@kentcdodds/why-semver-ranges-are-literally-the-worst-817cdcb09277)
_how:_
> `npm@5`以上で`package-lock.json`を使いましょう。
_npm@5 は使ってない:_
> `Yarn`を使い`README.md`を確かめることで代替手段とすることができます。各ライブラリをアップデートした後にロックファイルと`package.json` は同じバージョンを保持しているでしょう。
_`Yarn`という名前が気にくわない:_
> それは残念です。 古いバージョンの`npm`用に、パブリッシュする前に新しいライブラリをインストールしたり`npm-shrinkwrap.json`を作るときには、`—save --save-exact`を使いましょう。[もっと読む...](https://docs.npmjs.com/files/package-locks)
<a name="dependencies"></a>
## 4. 依存関係

- 使用可能な最新のパッケージを保ちましょう。 e.g.,`npm ls --depth=0`. [もっと読む...](https://docs.npmjs.com/cli/ls)
- 無関係であったり使っていないパッケージを確認しましょう: `depcheck`. [もっと読む...](https://www.npmjs.com/package/depcheck)
_Why:_
> もしかしたら使っていないライブラリが production のサイズを増加させているかもしれません。使っていない依存関係を見つけてそれを消すようにしましょう。
- ライブラリをインストールする前に、そのライブラリがコミュニティでよく使われているかどうかを確認しましょう。`npm-stat`。[もっと読む...](https://npm-stat.com/)
_Why:_
> 多く使われているということは多くのコントリビューターがいるということで、それは良いメンテナンスが行われているということになります。そのことはバグが開発者によっていち早く発見され、修正されることに繋がります
- ライブラリをインストールする前に、それがいい機能を持っているか、多くのメンテナーがいて成熟したバージョンを頻繁にリリースしているライブラリかを確認しましょう。: e.g., `npm view async`. [もっと読む...](https://docs.npmjs.com/cli/view)
_Why:_
> もしメンテナーが修正をマージしなかったりパッチを素早く当てないと、コントリビュータが効率的な開発を行えなくなるでしょう。
- それほど知られてないライブラリが必要な場合には、使用する前にチームメンバーと議論しましょう。
- ライブラリはビルドを破壊しない限りは常に最新で動くかを確かめましょう: `npm outdated` [もっと読む...](https://docs.npmjs.com/cli/outdated)
_Why:_
> 依存パッケージの更新はたまに破壊的変更が含まれていることがあります。アップデートが出たときには常にリリースノートを確認しましょう。何かあったときにトラブルシューティングを簡単にするために、依存ライブラリを一つ一つ更新しましょう。[npm-check-updates](https://github.com/tjunnone/npm-check-updates)のように素晴らしいツールを使いましょう。
- 依存パッケージに公開されている脆弱性が含まれている場合があるのでチェックしましょう。 e.g.,[Snyk](https://snyk.io/test?utm_source=risingstack_blog)
<a name="testing"></a>
## 5. テスト

- 必要であれば`test`の環境を用意しましょう。
_Why:_
> 通常は end to end のテストを`production`に行うだけで十分なですが、例外がいくつかあります。統計データを`production`環境で有効にしたくなく、テストデータでダッシュボードを汚したくない場合です。あとは`production`の API に制限があって、テストをする際のリクエスト数が制限に達してブロックされてしまう場合です。
- 単体テストコードはテストされるファイルの隣におきましょう。 `moduleName.spec.js`のように`*.test.js` や `*.spec.js` のようなファイル名が慣例となっています。
_Why:_
> ユニットテストを探すためにフォルダ構造を掘り進めたくないでしょう。[もっと読む...](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc)
- 追加のテストファイルがどこにあるか混乱を避けるために隔離されたフォルダに入れましょう
_Why:_
> いくつかのテストコードは実装コードと関連してないことがあります。他の開発者が見つけやすいフォルダ(`__test__`フォルダのような)にテストコードをおきましょう。`__test__`フォルダはスタンダートであり、様々な JavaScript フレームワークのテストで使用されています。
- テストの書きやすいコードを書きましょう。副作用を避けましょう。副作用を抽出しましょう。純粋な関数を書きましょう。
_Why:_
> 結合を分けてロジックのテストをしたい場合。ランダムで非決定性のプロセスがコードの信頼性に与える影響を最小にする必要があります。[もっと読む...](https://medium.com/javascript-scene/tdd-the-rite-way-53c9b46f45e3)
> 純粋関数は同じ入力に対して常に同じ結果を出力します。逆に言えば純粋でない関数は副作用をもっているか結果を出力する際に外部の状況に左右されます。そのような関数は予想通りの結果が返ってきにくくなります。[もっと読む...](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc)
- 静的解析ツールを使いましょう。
_Why:_
> 静的解析ツールが必要な場面があるかもしれません。コードが信頼できる基準をもたらしてくれます。
- `develop`ブランチにするリクエストを投げる前にローカルでテストを実行しましょう。
_Why:_
> 誰しもプロダクション準備中のビルドを失敗される犯人になりたくたいでしょう。`rebase`した後、リモートの feature ブランチにリポジトリに Push する前にテストを実行するようにしましょう。
- テストの実行方法などの情報を含めて、ドキュメントとして`README.md`ファイルに記述しましょう。
_Why:_
> ドキュメントを残すことで他の開発者、DevOps の担当者もしくは QA にプロジェクトを引き継いだ時に、彼らがあなたのコードで仕事をしやすくなります。
<a name="structure-and-naming"></a>
## 6. プロジェクトの構造と名前付け

- ファイルを役割ではなく商品、ページ、コンポーネントのように集約しましょう。テストファイルも実装の隣に配置しましょう。
**Bad**
```
.
├── controllers
| ├── product.js
| └── user.js
├── models
| ├── product.js
| └── user.js
```
**Good**
```
.
├── product
| ├── index.js
| ├── product.js
| └── product.test.js
├── user
| ├── index.js
| ├── user.js
| └── user.test.js
```
_Why:_
> 長いファイルのリストの代わりに、テストコードを含めたカプセル化された単一責任の小さいモジュールが出来上がります。そうすることでコードのガイドがしやすくなり、一目で見つけることができるようになります。
- 追加のテストファイルは混乱を避けるために test フォルダに置きましょう。
_Why:_
> 他の開発者やチームの DevOps の担当者の時間を節約することにつながります。
- `./config`フォルダを作成しましょう。違う環境のための違う config ファイルを作らないようにしましょう。
_Why:_
> 異なる目的(例えばデータベースや API 等々)のために複数の config ファイルに分割する時は、同じフォルダに`config`のようなわかりやすい名前でまとめておきましょう。ただし、異なる環境ごとに異なる config ファイルを作成しないように気をつけてください。新たなデプロイ先が増えた時に新たな環境の名前が必要となり、綺麗にスケールすることができないからです。
> config ファイル内の変数は環境変数から与えるのが良い方法です。[もっと読む...](https://medium.com/@fedorHK/no-config-b3f1171eecd5)
- スクリプトは`./scripts`フォルダに置きましょう。ここには node や bash のスクリプトが含まれます。
_Why:_
> プロダクション、デベロップのビルド、データベースの構築と同期等々を行う際に少なくとも一つ以上のスクリプトがプロジェクトで必要とされる可能性が高いでしょう。
- ビルドの成果物は`./build`に出力するようにしましょう。`build/`を`.gitignore`に加えましょう。
_Why:_
> 名前はなんでもよくて、dist という名前でもかっこいいです。なんでもいいとはいえ、チームのメンバーが矛盾なく理解できる名前でなければなりません。例えば何がそのフォルダで取得できるのか、作成されたものなのかバンドルされたものなのか、コンパイルされたものなのか、もしくはただ移動されてきたものなのか。なにを出力するのか、チームメートがそこになにを出力できるのかもそうです。だからそのフォルダは特殊な事情がない限りですがリモートリポジトリにコミットする必要がありません。
- `PascalCase`と`camelCase`をファイルとディレクトリの名前に使用しましょう。`PascalCase`はコンポーネントのみに使用しましょう。
- `CheckBox/index.js`は`CheckBox`のコンポーネントを持っているべきです。`CheckBox.js`もそうでしょう。しかし`CheckBox/CheckBox.js`や`checkbox/CheckBox.js`のような名前は冗長なので避けるべきです。
- 理想的にはフォルダの名前は`index.js`のデフォルト export の名前と一致させるべきです。
_Why:_
> そうすることで親フォルダをシンプルに import するだけでモジュールやコンポーネントを想像できます。
<a name="code-style"></a>
## 7. コードスタイル

<a name="code-style-check"></a>
### 7.1 コードスタイルガイドライン
- 新しいプロジェクトでは stage-2 かそれよりバージョンの新しいモダンな JavaScript を使用するようにしましょう。古いプロジェクトについては、モダンな JavaScript が動くプロジェクトにさせたい場合は別として既存のバージョンと互換性のあるバージョンにとどめておきましょう。
_Why:_
> チーム次第ではありますが、私たちはトランスパイラを使用することで、新しいシンタックスの利点を活用しています。stage-2 は残りわずかな改訂で仕様の一部になる可能性が徐々に高くなっています。
- コードスタイルチェックをビルドプロセスに含めましょう。
_Why:_
> ビルドを壊すことはコードスタイルを矯正する一つの方法になります。あなたがだんだんコードスタイルを真剣に捉えなくなるということを防いでくれます。クライアントとサーバーサイドのコード両方に導入しましょう。[もっと読む...](https://www.robinwieruch.de/react-eslint-webpack-babel/)
- コードスタイルを強制するために[ESLint - Pluggable JavaScript linter](http://eslint.org/)を使いましょう。
_Why:_
> 私たちはシンプルな `eslint` が好きなだけなので、あなたがそうである必要はないです。`eslint` 自体たくさんのルールをサポートしています。ルールを設定でき、カスタムルールを追加することができます。
- 私たちは[Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)を JavaScript に使っています。[もっと読む...](https://www.gitbook.com/book/duk/airbnb-javascript-guidelines/details)。あなたのチームに求められた JavaScript のスタイルガイドを使用しましょう。
- 私たちは[FlowType](https://flow.org/)を使用する時には[Flow type style check rules for ESLint](https://github.com/gajus/eslint-plugin-flowtype)を使っています。
_Why:_
> Flow には、特定のコードスタイルに従ってチェックする必要がある構文がほとんどありません
- 特定のフォルダやファイルをコードスタイルチェックから除外するために`.eslintignore`を使いましょう。
_Why:_
> 複数のファイルをスタイルチェックから除外する時に、`eslint-disable`のコメントでコードを汚す必要がありません。
- プルリクエストを作成する前には`eslint`のコメントアウトを削除しましょう。
_Why:_
> ロジックの実装に注力している時はスタイルチェックを無効にするのは一般的ですが、`eslint-disable` のコメントを削除してルールに従うことを忘れないようにしましょう。
- タスクのサイズによって、`//TODO:` コメント使うか、チケットを起票するかを選択しましょう。
_Why:_
> チームメートには小さなタスクの事(関数のリファクタリング、コメントのアップデートなど)を定義しておきましょう。大きめのタスクにはリントルール通りに`//TODO(#3456)`と書き、チケットの番号を記載しましょう。
- コメントは常にコードの変更に関連させるようにしましょう。コメントアウトされたコードは取り除きましょう。
_Why:_
> コードは可能な限り読みやすくする必要があると同時に、余分な部分は除去しておくべきです。リファクタリングする時は既存コードをコメントアウトするのではなく、削除しましょう。
- 無関係であったりおかしなコードやログや名前付けは避けましょう。
_Why:_
> ビルドプロセスでそれらを除去できるかも(すべき)です。あなたのコードは別会社や別クライアントの渡される可能性がありますし、あなたのコードがどこかの誰かに見られて笑われないようにしましょう。
- 短い名前を避けて、意味として区別しやすい検索しやすい名前をつけましょう。関数には長くて記述的な名前を使いましょう。関数の名前は動詞もしくは動詞のフレーズにしましょう。その関数の意図を伝える必要があります。
_Why:_
> ソースコードをより自然により読みやすくさせるためです。
- ファイル内の関数を降順によってまとめておきましょう。高いレベルの関数は上部へ、低いレベルの関数は下部へ位置させましょう。
_Why:_
> 読むのに適したソースコードになるようにするためです。
<a name="enforcing-code-style-standards"></a>
### 7.2 標準的なコードスタイルの強制
- .editorconfig ファイルを使って開発者が異なるエディタや IDE のプロジェクト間で一貫したコーディングスタイルを定義し維持することができるようにしましょう。
_Why:_
> EditorConfig プロジェクトはコーディングスタイル定義とエディタがファイルフォーマット読み込んでスタイル定義を有効にするエディタプラグインからなります。EditorConfig ファイルは可読性が高くバージョンコントロールシステムともうまく機能します。
- コードスタイルのエラーを伝えてくれるエディタを使いましょう。既存の ESLint の設定と一緒に[eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier)と[eslint-config-prettier](https://github.com/prettier/eslint-config-prettier)を使いましょう。[もっと読む...](https://github.com/prettier/eslint-config-prettier#installation)
- Git hook の使用を考えましょう。
_Why:_
> Git hook は開発者の生産性を大きく高めてくれます。ビルドの破壊を怖がることなく、ステージングやプロダクション環境に変更を作成、コミット、Push できます。[もっと読む...](http://githooks.com/)
- Prettier を`precommit hook`とともに使いましょう。
_Why:_
> `prettier`自体はとても力強いものではありますが、毎回のコードフォーマットに対して個別の npm task としてシンプルに実行することはあまり生産的ではありません。ここでは`lint-staged`(と`husky`)が活躍します。`lint-staged` [here](https://github.com/okonet/lint-staged#configuration)の`husky` [here](https://github.com/typicode/husky)の設定をよく読みましょう。
<a name="logging"></a>
## 8. ログ

- クライアントサイドの console ログをプロダクション環境で出力するのは避けましょう。
_Why:_
> ビルドプロセスを通して Console ログを取り除くことができます(すべきです)が、コードスタイルチェックが吐き出す console log についての warning の情報を確認しましょう。
- プロダクションのログは読みやすいように出力しましょう。理想的にはプロダクションモードで使われているロギングライブラリを使いましょう([winston](https://github.com/winstonjs/winston) もしくは
[node-bunyan](https://github.com/trentm/node-bunyan)のようなものがあります。)
_Why:_
> ログのカラー化やタイムスタンプ、ログファイルの出力や日々のログファイルのローテートが、トラブルシューティングの不快感を少なくしてくれます。
<a name="api"></a>
## 9. API
<a name="api-design"></a>

### 9.1 API デザイン
_Why:_
> 私たちは明快に構築された RESTful のインターフェースでの開発を強制することで、チームメンバーやクライアントがシンプルに矛盾なくそれを使えることができます。
_Why:_
> 一貫性やシンプルさがない API はシステムの結合やメンテナンスのコストを増加させます。だから`API design`をこのドキュメントに含めて説明しています。
- 私たちは多くの場面でリソース志向アーキテクチャに従っています。リソース志向アーキテクチャとは主にリソース、集合、URL の要素で構成されます。
- リソースはデータを持っていて、ネストを取得でき、それらのリソースを操作できるメソッドがあります。
- リソースの集合はコレクションと呼ばれます。
- URL はオンラインのリソースの場所はリソースかコレクションで表します。
_Why:_
> 上記のことは開発者(あなたの API を使う人たち)に周知されていることです。可読性や使いやすさを別としても、REST API ではその API の詳細を知らずとも汎用なライブラリやコネクタを書くができます。
- URL には kebab-case を使いましょう。
- リクエスト内のパラメータやリソース内のパラメータには camelCase を使いましょう。
- URL 内のリソース名は複数形の kebab-case にしましょう
- コレクションを表す url には常に複数形の名詞を使いましょう。`/users`
_Why:_
> 基本的にはそうすることで読みやすさの向上 URL の一貫性を維持することになるでしょう。[もっと読む...](https://apigee.com/about/blog/technology/restful-api-design-plural-nouns-and-concrete-names)
- ソースコード内での変数やプロパティ名の複数形はリストのサフィックスにしましょう。
_Why:_
> 複数形は URL においては良いものですが、ソースコード内では分かりにくくエラーの原因になり得ます。
- コレクションで始まり識別子に終わる単一のパスを常に使用しましょう。
```
/students/245743
/airports/kjfk
```
- 以下のような URL は避けましょう。
```
GET /blogs/:blogId/posts/:postId/summary
```
_Why:_
> この URL はリソースではなく、プロパティをさしています。プロパティはレスポンスを整えるようにパラメータに渡しましょう。
- リソースを示す URL からは動詞を含めないようにしましょう。
_Why:_
> 各リソースの操作に動詞を含めると、各々のリソースの操作について大量の URL が出来てしまい、開発者にとって理解するのが難しい一貫性のないパターンになってしまうからです。私たちは他の箇所に動詞を使っています。
- リソースではない部分に動詞を使用しましょう。このケースではこの API はリソースを返さずに、操作を実行して結果を受け取るのみです。CRUD(Create Retrieve Update Delete)の操作ではないことに注意しましょう。
```
/translate?text=Hallo
```
_Why:_
> CRUD についてはリソースやコレクションの URL に対して HTTP メソッドを使用するからです。説明している動詞はおおよそ`Controller`となります。通常これらの URL をたくさん作成することはないでしょう。[もっと読む...](https://byrondover.github.io/post/restful-api-guidelines/#controller)
- リクエストボディやレスポンスタイプは`JSON`にしましょう。そして一貫性あるメンテナンスをしやすくするために、プロパティ名は`camelCase`を使用するようにしましょう。
_Why:_
> このドキュメントは JavaScript プロジェクトのガイドラインであるため、JSON の読み書きには JavaScript が使用されてることを想定しています。
- リソースオブジェクトインスタンスや DB のレコードと同じような単一なものであったとしても、`table_name`や`column_name`はリソース名やプロパティ名にしないようにしましょう。
_Why:_
> あくまでリソースを公開するのであって DB のスキーマの詳細を公開するためのものではないからです。
- 念のためにもう一度、URL には名詞のみを使い、機能を説明するような名前付けは避けましょう。
_Why:_
> 名詞のみをリソースの URL には使用しましょう。`/addNewUser`や`/updateUse`のようなエンドポイントを用意するのはやめましょう。同様にリソース操作をパラメータを送るのも避けましょう。
- CRUD の機能的説明には HTTP のメソッドを使いましょう。
_How:_
> `GET`: 存在するリソースの取得。
> `POST`: 新しいリソースとサブリソースの作成。
> `PUT`: 既存のリソースの更新。
> `PATCH`: 既存のリソースの更新。提供されたフィールドのみを更新し、他のフィールドはそのままにしておきます。
> `DELETE`: 存在するリソースの削除。
- ネストしているリソースのために関連する URL 間にリレーションを使用しましょう。例えば会社の従業員を関連されるために、id を使用します。
_Why:_
> 各リソースを探索しやすくするための自然なやり方です。
_How:_
> `GET /schools/2/students `。2 の学校のすべての生徒を取得できるはずです。
> `GET /schools/2/students/31` 。2 の学校に所属する、31 の生徒の詳細を取得できるはずです。
> `DELETE /schools/2/students/31` 。2 の学校に所属する 31 の生徒を削除できるはずです。
> `PUT /schools/2/students/31` 。31 の生徒の情報を更新するはずです。また PUT はコレクションには使用せずにリソース URL のみに使用するようにしましょう。
> `POST /schools`。新たな学校を作成して、その作成された学校の情報を返却するはずです。POST はコレクションの URL に使用しましょう。
- バージョンには`v`をプレフィックスとした単純な整数を使用しましょう(v1,v2)。全ての URL を残したまま移動するために、バージョンは一番上のスコープに使用しましょう。
```
http://api.domain.com/v1/schools/3/students
```
_Why:_
> API がサードパーティのために公開される時には、API の破壊的変更を伴うバージョンアップは既存のプロダクトや API を使うサービスに多大な影響を与えます。バージョンを URL に含めることで、これらの問題が起きることを防いでくれます。[もっと読む...](https://apigee.com/about/blog/technology/restful-api-design-tips-versioning)
- レスポンスメッセージは自己記述的でなければなりません。良いエラーレスポンスは以下のようなものになります。
```json
{
"code": 1234,
"message": "Something bad happened",
"description": "More details"
}
```
またバリデーションエラーならこうです。
```json
{
"code": 2314,
"message": "Validation Failed",
"errors": [
{
"code": 1233,
"field": "email",
"message": "Invalid email"
},
{
"code": 1234,
"field": "password",
"message": "No password provided"
}
]
}
```
_Why:_
> API を使用したアプリケーションがそのユーザーの手元に届けられたあと、問題解決やトラブルシューティングをする重要な時に、開発者は良いデザインのエラーメッセージに頼ることになります。
_Note: セキュリティの例外のメッセージは極力一般化しましょう。例えば"パスワードが間違っています"と言う代わりに、"ユーザー名もしくはパスワードが間違っています"と言いましょう。私たちの場合はユーザー名が正しくて、パスワードだけ間違っていると伝えることはしないようにしています。_
- **全てがうまく動いていた**、**クライアントアプリがうまく動いてなかった** 、**API がうまく動いてなかった** 等
レスポンスの説明には 8 個のステータスのみを送るようにしましょう。
_一覧:_
> `200 OK` `GET`、`PUT` 、`POST`リクエストが成功したことを表します。
> `201 Created` 新しいインスタンスが作成された時に返却されます。新しいインスタンスの作成、`POST`メソッドの使用は`201`のステータスコードを返します。
> `304 Not Modified` ユーザーがすでにレスポンスのキャッシュを持っている場合に返却されます、最小の転送に抑えることになります。
> `400 Bad Request` リクエストが処理されなかった場合に返却されます。サーバーがクライアントの要求するリクエストを理解できなかったような時です。
> `401 Unauthorized` リクエストの認証情報が不足している時に返却されます。要求された認証情報で再リクエストを行うことになるでしょう。
> `403 Forbidden` サーバーはリクエストを解釈できていますが、認証を拒否したという意味です。
> `404 Not Found` リクエストしたリソースが見つからなかったことを示します。
> `500 Internal Server Error` リクエストは正しいが、サーバーが予期せぬ事態により動作しなかったことを示します。
_Why:_
> 多くのAPIの提供者は少数のHTTPのステータスコードを使用します。例えばGoogleのGdata APIは10個のステータスコードしか使っていません。Netflixは9つです。Diggは8つだけです。もちろんながらこれらのレスポンスは追加の情報をbodyに含めています。70を超えるHTTPのステータスが存在しますが。あまり一般的でないステータスコードを選択すると、アプリケーションの開発者は開発を離れて、ステータスコードが何を示しているのかを理解しようとwikipedia等で調べざるを得なくなります。[もっと読む...](https://apigee.com/about/blog/technology/restful-api-design-what-about-errors)
- レスポンスにはリソースの数の合計を提供しましょう。
- `limit`と`offset`のパラメータを受けつけましょう。
- リソースの公開するデータ量はよく考える必要があります。API の利用者は常にリソースの全ての表現が必要というわけではありません。フィールドのカンマ区切りリストを含むフィールドクエリパラメータを使用します。
```
GET /student?fields=id,name,age,class
```
- ページネーション、フィルタリング、ソートは初めから全てのリソースをサポートする必要はありません。フィルタリングやソートのあとにこれらのリソースを記述しましょう。
<a name="api-security"></a>
### 9.2 API セキュリティ
いくつかのセキュリティのベストプラクティスをご紹介します。
- セキュアな通信(HTTPS)以外ではベーシック認証を使わないようにしましょう。認証トークンを URL に含めてはいけません。`GET /users/123?token=asdf....`
_Why:_
> トークンやユーザー ID やパスワードが平文としてネットワークを超えてくるので(base64 にエンコードされているでしょうが、base64 は可逆なエンコード方法です。)、ベーシック認証機構はセキュアではないです。[もっと読む...](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication)
- トークンは毎回のリクエストの認証ヘッダーに乗せて送信されなければなりません。`Authorization: Bearer xxxxxx, Extra yyyyy`
- 認証コードの生存期間は短く設定されるべきです。
- 安全ではないデータの受け渡しを避けるために HTTP リクエストに応答しないことで TLS ではないリクエストを拒否するようにしましょう。その際には`403 Forbidden`で応答しましょう。
- リクエスト制限を使うことを考えましょう。
_Why:_
> 一時間あたり何千ものリクエストを送りつけてくるボットから身を守るために、リクエスト制限を早いうちから考えておくべきでしょう。
- HTTP ヘッダを適切に設定することは Web アプリケーションをより強固に、より安全にするのに役立ちます。[もっと読む...](https://github.com/helmetjs/helmet)
- API は標準的なフォームのデータを受け取ってデータを加工しましょう。できなければリクエストを拒否するようにしましょう。400 Bad Request とともにデータの不足やエラーについての詳細を返却しましょう。
- REST な API で交換される全てのデータは API 上で Validate するようにしましょう。
- JSON をシリアライズしましょう。
_Why:_
> JSON エンコーダの悩みの種は、ブラウザ内でリモートからの任意の JavaScript の実行を防ぐことです。もしくは node.js を使用しているのであれば、サーバーサイドも同様です。ユーザーから与えられた入力がブラウザ内で実行されないように、ユーザーからの情報をエンコードできる適切な JSON シリアライザーを使用することが重要です。
- Content-Type を Validate するようにしましょう。多くの場合で `application/*json` (Content-Type ヘッダ)を使いましょう。
_Why:_
> 例えば、`application/x-www-form-urlencoded`の mime-type を受け入れることは、攻撃者にフォームを作成させ、シンプルな POST リクエストを誘引させることを許すことになります。サーバは受け入れる Content-Type を決して推定させないべきです。Content-Type ヘッダもしくは予期しない Content-Type ヘッダに対しては`4XX`のレスポンスでリクエストを拒否する結果を返却しましょう。
- API のセキュリティをチェックリストを見て確認しましょう。[もっと読む...](https://github.com/shieldfy/API-Security-Checklist)
<a name="api-documentation"></a>
### 9.3 API ドキュメント
- [README.md template](./README.sample.md)の`API Reference`のセクションを埋めましょう。
- コードのサンプルとともに API の認証方法について記述しましょう。
- URL の構造(path についてのみでいいです。root の URL については必要ありません。)をリクエストのメソッドとともに説明しましょう。
各エンドポイントについて
- URL パラメータはもし存在する場合は、URL セクションに記載されている名前に従って指定しましょう。
```
Required: id=[integer]
Optional: photo_id=[alphanumeric]
```
- リクエストタイプが POST なら、ちゃんと動く例も用意しましょう。URL パラメータのルールはここにも適用します。Optional と Required に分けましょう。
- レスポンスの成功の場合ステータスコードは何でしょうか?どんなデータを返されるでしょうか?ドキュメントは API の返答を開発者が知りたいときに役立ちます。
```
Code: 200
Content: { id : 12 }
```
- レスポンスの失敗の時は、ほとんどのエンドポイントの失敗は複数通りあります。認証されていないアクセスからの不正な値等。それら全てをここでは列挙しましょう。繰り返しになりますが、こうすることで憶測のみで開発せざるを得ない状況を防ぎます。例
```json
{
"code": 403,
"message": "Authentication failed",
"description": "Invalid username or password"
}
```
- API デザインツールを使用しましょう。[API Blueprint](https://apiblueprint.org/)、[Swagger](https://swagger.io/)のようなオープンソースの良いドキュメンテーションツールがたくさんあります。
<a name="licensing"></a>
## 10. ライセンス

使用できる権利のあるリソースを使用していることを確認してください。ライブラリを使っているのであれば、MIT、Apache、BSD のライセンスを見つけることを心がけましょう。ライブラリを修正したいのであれば、ライセンスの詳細を少し見て見ましょう。著作権で保護されている画像や動画が法的問題を引き起こすかもしれません。
---
Sources:
[RisingStack Engineering](https://blog.risingstack.com/),
[Mozilla Developer Network](https://developer.mozilla.org/),
[Heroku Dev Center](https://devcenter.heroku.com),
[Airbnb/javascript](https://github.com/airbnb/javascript),
[Atlassian Git tutorials](https://www.atlassian.com/git/tutorials),
[Apigee](https://apigee.com/about/blog),
[Wishtack](https://blog.wishtack.com)
Icons by [icons8](https://icons8.com/)
================================================
FILE: README-ko.md
================================================
[ENGLISH](./README.md)
| [中文版](./README-zh.md)
| [日本語版](./README-ja.md)
| [РУССКИЙ](./README-ru.md)
| [Português](./README-pt-BR.md)
| [Persian/فارسی](./README-ir.md)
[<img src="./images/elsewhen-logo.png" width="180" height="180">](https://www.elsewhen.com/)
# Project Guidelines · [](http://makeapullrequest.com)
> 새로운 프로젝트를 개발하는 할 때는 초원에서 뛰어노는 것 같지만, 유지보수는 모두에게 잠재적인 악몽입니다.
> 이것은 우리가 발견하고, 작성하고 수집한 가이드라인의 목록입니다. 이 가이드라인은 대부분의 [elsewhen](https://www.elsewhen.com)에서의 JavaScript 프로젝트에 잘 맞습니다.
> 만약 모범 사례를 공유하고 싶으시거나 여기에 있는 가이드라인 중 어떤 것이 지워져야 한다고 생각하신다면, [부담없이 우리에게 공유해주세요](http://makeapullrequest.com).
- [Git](#git)
- [Git 규칙](#some-git-rules)
- [Git 워크플로우](#git-workflow)
- [좋은 커밋 메시지 작성하기](#writing-good-commit-messages)
- [문서화](#documentation)
- [환경](#environments)
- [일관적인 개발환경](#consistent-dev-environments)
- [일관적인 의존성](#consistent-dependencies)
- [의존성](#dependencies)
- [테스트](#testing)
- [구조 및 네이밍](#structure-and-naming)
- [코드 스타일](#code-style)
- [코드 스타일 가이드라인](#code-style-check)
- [표준 코드 스타일 강제하기](#enforcing-code-style-standards)
- [로깅](#logging)
- [API](#api)
- [API 설계](#api-design)
- [API 보안](#api-security)
- [API 문서화](#api-documentation)
- [라이센스](#licensing)
<a name="git"></a>
## 1. Git

<a name="some-git-rules"></a>
### 1.1 Git 규칙
Git에는 명심해야할 규칙들이 있습니다.
- feature 브랜치(branch)에서 작업하세요.
_이유:_
> 이 방법을 사용하면 모든 작업은 메인 브랜치 대신에 격리된 별도의 브랜치에서 하게 됩니다. 이렇게 하면 혼란 없이 여러개의 풀 리퀘스트(Pull Request)를 제출할 수 있습니다. 또한 잠재적으로 불안정한, 완료되지 않은 코드로 마스터 브랜치를 오염시키지 않고, 작업을 반복할 수 있습니다. [더 알아보기](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow)
- `develop`에서 브랜치를 만드세요.
_이유:_
> 이 방법을 사용하면, 마스터 브랜치의 코드를 항상 거의 문제없이 빌드할 수 있고, 릴리즈를 위해서 직접 사용할 수도 있습니다 (일부 프로젝트의 경우 과할 수도 있음).
- `develop`과 `master`에 직접 푸시하지 않고, 풀 리퀘스트를 만드세요.
_이유:_
> 풀 리퀘스트는 기능 구현을 완료한 것을 다른 팀 멤버들에게 알립니다. 또한 쉬운 코드 리뷰를 가능케 하며, 제안된 기능에 대해 토론할 수 있는 포럼을 제공합니다.
- 개발한 기능을 푸시하고 풀 리퀘스트를 만들기 전에, 로컬 `develop` 브랜치를 업데이트하고 인터랙티브한 리베이스(rebase)를 진행하세요.
_이유:_
> 리베이스는 요청한 브랜치(`master` 혹은 `develop`)을 병합(merge)합니다. 또한 병합 커밋을 만들지 않으면서 로컬에서 만든 커밋들을 적용합니다 (충돌이 없다고 가정한다면). 결국 깨끗한 히스토리를 남기게 됩니다. [더 알아보기](https://www.atlassian.com/git/tutorials/merging-vs-rebasing)
- 풀 리퀘스트를 만들기 전에 리베이스하는 동안 잠재적인 충돌을 제거하세요.
- 병합 후, 로컬과 원격에 있는 feature 브랜치를 삭제하세요.
_이유:_
> 이 방법은 더 이상 사용하지 않는 브랜치들로부터 브랜치 리스트를 정리할 것입니다. 또한, 브랜치가 `master` 또는 `develop`으로 병합되는 것을 단 한 번으로 보장합니다. feature 브랜치는 작업이 진행되고 있는 도중에만 존재해야 합니다.
- 풀 리퀘스트를 생성하기 전에, feature 브랜치는 잘 빌드되는지, 코드 스타일 체크를 포함한 모든 테스트를 통과하는 지 검증하세요.
_이유:_
> 안정적인 브랜치에 코드를 새로 푸시하려 할 때, 만약 feature 브랜치의 테스트가 실패한다면, 목표한 브랜치의 빌드도 실패할 가능성이 높습니다. 또한 풀 리퀘스트를 만들기 전에 코드 스타일 검사를 적용해야합니다. 이렇게 하면 가독성을 높이고, 코드에 실제 변경사항을 작성할 때 포맷을 수정하는 변경사항이 섞일 가능성을 낮춥니다.
- 이 [.gitignore file](./.gitignore)을 사용하세요.
_이유:_
> 이 파일에는 이미 원격 저장소에 코드와 함께 보내면 안되는 시스템 파일 목록이 있습니다. 또한 이 파일은 가장 많이 사용되는 에디터와 대부분의 공통 의존성 폴더에 대한 폴더 및 파일 설정을 포함하고 있습니다.
- `develop`과 `master` 브랜치를 보호하세요.
_이유:_
> 이 방법은 예측하지 못한, 돌이킬 수 없는 변경으로부터 production-ready 브랜치들을 보호합니다. 더 알아보기: [Github](https://help.github.com/articles/about-protected-branches/), [Bitbucket](https://confluence.atlassian.com/bitbucketserver/using-branch-permissions-776639807.html)
<a name="git-workflow"></a>
### 1.2 Git 워크플로우
상기한 이유들 때문에, 우리는 [인터랙티브 리베이스](https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing), 그리고 [Gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows#gitflow-workflow)의 몇가지 요소(브랜치 네이밍과 develop 브랜치의 보유)와 함께 [Feature 브랜치 워크플로우](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow)를 사용해야 합니다. 주요 단계는 다음과 같습니다.
- 새로운 프로젝트의 경우, 프로젝트 디렉토리에 Git 레포지토리를 초기화하세요. **유지보수 작업의 경우 이 단계는 무시하세요**.
```sh
cd <project directory>
git init
```
- 새로운 feature/bug-fix 브랜치를 체크아웃하세요.
```sh
git checkout -b <branchname>
```
- 변경사항을 작성하세요.
```sh
git add
git commit -a
```
_이유:_
> `git commit -a`는 제목과 본문을 분리시킨 상태로 에디터를 엽니다. *섹션 1.3*에서 자세히 알아보세요.
- 놓친 변경사항을 받기 위해 원격 저장소와 동기화하세요.
```sh
git checkout develop
git pull
```
_이유:_
> 이렇게 하면 충돌(conflict)을 포함하는 풀 리퀘스트를 만드는 대신에, 당신의 컴퓨터에서 리베이스함으로써 충돌을 처리할 수 있습니다.
- 인터랙티브한 리베이스를 통해 develop 브랜치의 마지막 변경사항을 feature 브랜치로 업데이트 하세요.
```sh
git checkout <branchname>
git rebase -i --autosquash develop
```
_이유:_
> --autosquash를 사용해서 모든 커밋을 하나의 커밋으로 밀어 넣을 수도 있습니다. develop 브랜치에서 하나의 기능을 위한 많은 커밋들은 아무도 원하지 않기 때문이죠. [더 알아보기](https://robots.thoughtbot.com/autosquashing-git-commits)
- 만약 충돌이 발생하지 않았다면 이 단계를 건너뛰어도 좋습니다. 충돌이 발생했다면, [그것을 해결(resolve)하고](https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/) 리베이스를 계속하세요.
```sh
git add <file1> <file2> ...
git rebase --continue
```
- 브랜치를 푸시하세요. 리베이스는 이력을 변경시킵니다. 따라서 당신은 `-f`를 사용해서 원격 브랜치로 강제 변경해야합니다. 만약 다른 누군가가 당신의 브랜치에서 작업하고 있다면, 조금 덜 파괴적인 `--force-with-lease`를 사용하세요.
```sh
git push -f
```
_이유:_
> 리베이스 할 때, 당신은 feature 브랜치의 이력을 변경하고 있는 겁니다. 그 결과, Git은 일반적인 `git push`를 거부합니다. 대신, 당신은 -f 혹은 --force 플래그를 사용할 필요가 있습니다. [더 알아보기](https://developer.atlassian.com/blog/2015/04/force-with-lease/)
- 풀 리퀘스트를 만드세요.
- 풀 리퀘스트는 리뷰어에 의해 수용되고, 병합되고 종료될 것 입니다.
- 모든 작업이 끝났다면 당신의 로컬 feature 브랜치는 지우세요.
```sh
git branch -d <branchname>
```
원격 저장소에 존재하지 않는 모든 브랜치를 제거하기 위해서는 다음과 같이 하면 됩니다.
```sh
git fetch -p && for branch in `git branch -vv | grep ': gone]' | awk '{print $1}'`; do git branch -D $branch; done
```
<a name="writing-good-commit-messages"></a>
### 1.3 좋은 커밋 메시지 작성하기
커밋을 작성하는 좋은 가이드라인을 가지고 있으면 Git으로 작업하거나 다른 사람들과 협업하는 것이 상당히 쉬워집니다. 다음은 그 규칙들입니다. ([출처](https://chris.beams.io/posts/git-commit/#seven-rules))
- 줄 바꿈을 통해서 제목과 본문을 구분하세요.
_이유:_
> Git은 당신의 커밋 메시지의 첫번째 줄을 요약으로 분간할만큼 똑똑합니다. 사실, git log 대신에 git shortlog를 사용하면 커밋 ID와 요약정보만이 표시된 커밋 메시지의 긴 리스트를 볼 수 있습니다.
- 제목을 50자로, 본문은 72자로 제한하세요.
_이유:_
> 커밋은 가능한 보기 좋고 집중되어야하며, 장황하게 설명해서는 안됩니다. [더 알아보기](https://medium.com/@preslavrachev/what-s-with-the-50-72-rule-8a906f61f09c)
- 제목에 대문자를 사용하세요.
- 제목을 마침표로 끝내지마세요.
- 제목에 [명령법(imperative mood)](https://en.wikipedia.org/wiki/Imperative_mood)을 사용하세요.
_이유:_
> 커미터가 완료한 일을 표현하는 메시지를 작성하는 것이 아닙니다. 이런 메시지들은 커밋이 레포지토리에 적용된 뒤에 어떻게 되는지를 설명하는 것으로 간주하는 것이 낫습니다. [더 읽기](https://news.ycombinator.com/item?id=2079612)
- 본문은 **어떻게** 대신 **무엇을**과 **왜**를 설명하는데 사용하세요.
<a name="documentation"></a>
## 2. 문서화

- `README.md`를 위해서 이 [템플릿](./README.sample.md)을 사용하세요. 필요한 섹션은 자유롭게 추가하세요.
- 한 개 이상의 레포지토리가 있는 프로젝트는 각각의 `README.md` 파일에 링크를 추가해주세요.
- 프로젝트가 발전함에 따라 `README.md`를 최신으로 유지하세요.
- 코드에 주석을 달아주세요. 가능하다면, 각 섹션에서 무엇을 표현하려고 하는지 명확하게 만드세요.
- GitHub 혹은 StackOverflow에 당신이 사용한 접근법이나 코드에 대한 토론이 있다면, 주석에 그 링크를 첨부하세요.
- 주석을 나쁜 코드에 대한 변명으로 사용하지 마세요. 코드를 깔끔하게 유지하세요.
- 클린 코드는 주석을 전혀 달지 않는 것에 대한 변명이 아닙니다.
- 코드가 발전함에 따라 주석도 적절하게 바꿔주세요.
<a name="environments"></a>
## 3. 환경

- 필요하다면 `development`, `test`와 `production` 환경을 분리하세요.
_이유:_
> 다른 데이터, 토큰, API, 포트 등... 아마도 별도의 환경을 필요로 할 것입니다. 아마도 당신은 격리된 `development` 모드에서는 가짜 API를 호출하고 예상가능한 데이터를 리턴해서 수동/자동 테스트를 보다 쉽게 할 수 있게 하는 것을 원할 겁니다. 혹은 Google Analytics를 `production` 모드에서만 사용하고 싶을 수도 있습니다. [더 읽기](https://stackoverflow.com/questions/8332333/node-js-setting-up-environment-specific-configs-to-be-used-with-everyauth)
- 배포에 관련된 설정 변수들은 환경 변수에서 불러오도록 하고 그 변수들을 코드 베이스에 상수로 포함하지 마세요. [이 샘플을 참고하세요](./config.sample.js).
_이유:_
> 당신은 토큰이나 비밀번호 혹은 그 외에 중요한 정보를 가지고 있을 겁니다. 언제든지 코드베이스를 공개할 수 있을 것처럼 설정 변수는 어플리케이션의 내부와 제대로 구분되어야 합니다.
_방법:_
> `.env` 파일을 당신의 변수들을 저장하는 용도로 사용하고, 그 파일을 `.gitignore`에 넣어 제외하세요. 대신에, 다른 개발자들에게 가이드를 제공하는 `.env.example` 이라는 파일을 커밋하세요. 프로덕션 환경에서는 표준적인 방법으로 환경 변수를 설정헤야 합니다. [더 읽기](https://medium.com/@rafaelvidaurre/managing-environment-variables-in-node-js-2cb45a55195f)
- 어플리케이션이 실행되기 전에 환경 변수를 검증(validate)하는 것을 추천합니다. 값들을 검증하기 위해 `joi`를 사용하고 있는 [이 샘플을 참고하세요](./configWithTest.sample.js).
_이유:_
> 다른 이들을 트러블슈팅에서 구해낼 수 있습니다.
<a name="consistent-dev-environments"></a>
### 3.1 일관적인 개발 환경
- `package.json`의 `engines`에 Node.js 버전을 설정하세요.
_이유:_
> 다른 이들에게 프로젝트가 동작하는 Node.js 버전에 대해 알려줄 수 있습니다. [더 읽기](https://docs.npmjs.com/files/package.json#engines)
- 추가로, `nvm`을 사용하고 `.nvmrc` 파일을 프로젝트의 루트 경로에 만드세요. 문서에 그것을 명시하는 것도 잊지마세요.
_이유:_
> `nvm`을 사용하는 사람이라면 `nvm use` 명령어를 사용해서 간단하게 적절한 Node.js 버전으로 전환할 수 있습니다. [더 읽기](https://github.com/creationix/nvm)
- `preinstall`을 사용해서 Node.js와 npm 버전을 체크하는 것도 좋은 방법입니다.
_이유:_
> 어떤 의존(dependency)은 새로운 npm 버전으로 설치할 때 실패할 수도 있습니다.
- 가능하다면 도커 이미지를 사용하세요.
_이유:_
> 도커는 전체적인 워크플로우에 걸쳐 일관적인 환경을 제공합니다. 사용하지 않으면 의존성 혹은 설정에 많은 작업이 필요할 수도 있습니다. [더 읽기](https://hackernoon.com/how-to-dockerize-a-node-js-application-4fbab45a0c19)
- 글로벌로 모듈을 설치하지 말고 로컬 모듈을 사용하세요.
_이유:_
> 당신의 툴을 동료들이 글로벌로 설치하지 않고 당신이 사용하는 툴을 공유하도록 해줍니다.
<a name="consistent-dependencies"></a>
### 3.2 일관적인 의존성
- 다른 팀 멤버들이 당신과 정확히 같은 의존성을 갖도록 하세요.
_이유:_
> 왜냐면 당신은 어떤 개발 기기에서도 코드가 예상한대로 동일하게 동작하는 것을 원하니까요. [더 읽기](https://medium.com/@kentcdodds/why-semver-ranges-are-literally-the-worst-817cdcb09277)
_방법:_
> `npm@5` 이상의 버전에서 `package-lock.json`을 사용하세요.
_저는 npm@5 버전 미만이에요:_
> 대안으로 `Yarn`을 사용할 수 있습니다. `README.md`에 Yarn에 대해 확실히 명시하세요. 당신의 락(lock) 파일과 `package.json` 파일은 각 의존성 업데이트 후 동일한 버전을 가져야 합니다. [더 읽기](https://yarnpkg.com/en/)
_저는 `Yarn`이라는 이름이 싫은데요:_
> 유감입니다. 구 버전의 `npm`에서는 새로운 의존을 설치할 때 `-—save --save-exact`를 사용해서 올리기 전에 `npm-shrinkwrap.json`을 생성하세요. [더 읽기](https://docs.npmjs.com/files/package-locks)
<a name="dependencies"></a>
## 4. 의존성

- `npm ls --depth=0`를 사용해서 현재 사용 가능한 패키지를 추척하세요. [더 읽기](https://docs.npmjs.com/cli/ls)
- `depcheck`를 사용해서 패키지 중에 사용되지 않거나 관련이 없는 패키지가 있는지 확인하세요. [더 읽기](https://www.npmjs.com/package/depcheck)
_이유:_
> 당신은 쓰이지 않고 있는 라이브러리를 당신의 코드에 포함할 수도 있고 그로인해 프로덕션의 번들 사이즈가 커집니다. 쓰이지 않는 의존성을 찾아 제거하세요.
- 의존을 사용하기 전에, `npm-stat`을 사용해 커뮤니티에서 잘 사용되는 패키지인지 확인하기 위해서 다운로드 통계를 확인하세요. [더 읽기](https://npm-stat.com/)
_이유:_
> 대개, 사용량이 많을 수록 기여자(contributor)가 더 많아지므로, 유지 보수가 잘 됩니다. 또한, 이로 인해 버그가 빠르게 발견되고 고쳐집니다.
- 의존을 사용하기 전에, 많은 메인테이너와 함께, 성숙한 버전 릴리즈 주기가 있는지 확인하세요. 예: `npm view async` [더 읽기](https://docs.npmjs.com/cli/view)
_이유:_
> 아무리 많은 컨트리뷰터가 있어도 메인테이너들이 패치를 충분히 빠르게 머지(merge)하지 않으면 소용이 없습니다.
- 덜 알려진 의존성이 필요한 경우, 그걸 사용하기 전에 팀 내에서 의논하세요.
- `npm outdated`를 사용해서 당신의 어플리케이션이 깨지지 않고 의존 패키지의 최신 버전으로 동작하도록 만드세요. [더 읽기](https://docs.npmjs.com/cli/outdated)
_이유:_
> 의존은 때때로 깨트리는 변화(breaking change)를 담은 채로 업데이트 됩니다. 항상 업데이트가 있을 때마다 릴리즈 노트를 확인하세요. 당신의 의존성을 한 번에 하나씩 업데이트하면, 뭔가 잘못되었을 때 트러블슈팅이 쉬워집니다. [npm-check-updates](https://github.com/tjunnone/npm-check-updates) 같이 좋은 툴을 활용하세요.
- [Snyk](https://snyk.io/test?utm_source=risingstack_blog) 같은 것을 사용해서 패키지에 알려진 보안 취약점이 있는지 확인하세요.
<a name="testing"></a>
## 5. 테스트

- 필요하다면 `test` 모드를 만드세요.
_이유:_
> 때때로 프로덕션 모드로도 End-to-End 테스트에 충분할 수도 있지만, 예외는 항상 있습니다. 예를 들어, 당신은 프로덕션 모드를 사용해서 다른 사람의 대시보드를 테스트 데이터로 오염시키는 것을 원하지 않을 수도 있습니다. 다른 예로, 프로덕션 모드에서 당신이 사용하는 API는 호출 수 제한을 가져서, 일정량의 요청 후에는 테스트 호출을 차단할 수 있습니다.
- 테스트 파일을 테스트 되는 모듈과 같은 경로에 위치시키고 `moduleName.spec.js` 처럼 `*.test.js`나 `*.spec.js` 같은 네이밍 컨벤션으로 이름을 지어주세요.
_이유:_
> 유닛 테스트를 찾기 위해서 폴더 구조를 다 뒤지길 원하는 사람은 없을 겁니다. [더 읽기](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc)
- 혼란을 방지하기 위해 추가적인 테스트 파일들은 별도의 테스트 폴더에 넣으세요.
_이유:_
> 몇몇 테스트 파일들은 여러 개의 구현 파일과 관련이 있습니다. 당신은 그 파일들을 다른 개발자들이 찾을 가능성이 큰 `__test__` 폴더에 집어 넣어야 합니다. 또한, 이제 이 `__test__`라는 이름은 표준이며, 대부분의 JavaScript 테스트 프레임워크에 의해 사용되고 있습니다.
- 테스트 가능한 코드를 작성하세요. 사이드 이펙트를 피하세요. 사이드 이펙트를 분리하세요. 순수 함수를 작성하세요.
_이유:_
> 당신은 비즈니스 로직을 별개의 유닛으로 분리해 테스트 하기를 원할 겁니다. 그렇다면 당신은 "무작위의 영향과 코드 안정성에 대한 비결정적(nondeterministic) 프로세스를 최소화" 해야 합니다. [더 읽기](https://medium.com/javascript-scene/tdd-the-rite-way-53c9b46f45e3)
> 순수 함수는 같은 입력에 대해 항상 같은 출력을 돌려주는 함수를 말합니다. 반대로, 불순(impure) 함수는 사이드 이펙트를 포함하고 있거나 값을 얻기 위해 바깥의 상태에 의존하는 함수를 말합니다. 이러한 특징은 함수를 예측하기 어렵게 만듭니다. [더 읽기](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc)
- 정적 타입 분석기를 활용하세요.
_이유:_
> 이따금 당신은 정적 타입 분석기가 필요할 수도 있습니다. 정적 타입 분석기는 코드에 일정 수준의 신뢰도를 제공합니다. [더 읽기](https://medium.freecodecamp.org/why-use-static-types-in-javascript-part-1-8382da1e0adb)
- `develop`에 풀 리퀘스트를 만들기 전에 테스트를 로컬로 돌리세요.
_이유:_
> 프로덕션 준비된 브랜치의 빌드를 실패한 사람이 되고 싶진 않을 겁니다. 당신의 기능 브랜치를 원격 저장소에 푸시하기 전에 먼저 `rebase` 한 뒤 테스트를 돌리세요.
- `README.md` 파일의 적절한 섹션에 설명을 포함해서 테스트에 대해 문서화하세요.
_이유:_
> 다른 개발자 혹은 DevOps 전문가나 QA, 아니면 당신의 코드를 가지고 일하는 운 좋은 누군가에게 남겨두는 편리한 메모입니다.
<a name="structure-and-naming"></a>
## 6. 구조 및 네이밍

- 프로덕트를 구성하는 파일을 역할이 아닌 기능, 페이지, 컴포넌트 단위로 구성하세요. 또한, 테스트 파일은 구현 파일과 같은 경로에 두세요.
**Bad**
```
.
├── controllers
| ├── product.js
| └── user.js
├── models
| ├── product.js
| └── user.js
```
**Good**
```
.
├── product
| ├── index.js
| ├── product.js
| └── product.test.js
├── user
| ├── index.js
| ├── user.js
| └── user.test.js
```
_이유:_
> 긴 파일 리스트 대신에, 테스트를 포함해서 하나의 책임을 캡슐화한 작은 모듈을 만들게 될 겁니다. 그렇게 하면 파일 탐색이 훨씬 쉬워지고, 훑어봐도 파일을 찾을 수 있습니다.
- 혼란을 방지하기 위해 추가적인 테스트 파일들은 별도의 테스트 폴더에 넣으세요.
_이유:_
> 다른 개발자 혹은 DevOps 전문가 들의 시간을 아껴줄 수 있습니다.
- `./config` 폴더를 사용하고 다른 환경을 위해 다른 설정 파일을 만들지 마세요.
_이유:_
> 서로 다른 목적(데이터베이스, API 등)을 위해 설정 파일을 분리할 때, 그 파일들을 한 폴더에 넣고 `config` 처럼 잘 알려진 이름을 가진 폴더에 넣으면 됩니다. 그냥 다른 환경을 위해 다른 설정 파일을 만들지 말라는 것만 기억하세요. 그렇게 하면 깔끔하게 확장할 수 없습니다. 앱의 더 많은 배포판이 만들어지면 새로운 환경의 이름이 필요합니다. 설정 파일에서 사용되는 값들은 환경 변수에 의해 제공되어야 합니다. [더 읽기](https://medium.com/@fedorHK/no-config-b3f1171eecd5)
- 스크립트 파일들은 `./scripts` 폴더에 넣으세요. `bash`와 `node` 스크립트를 포함해서요.
_이유:_
> 당신은 프로덕션 빌드, 개발용 빌드, 데이터베이스 공급, 데이터베이스 동기화 등, 최소 1개 이상의 스크립트를 필요로 할 가능성이 높습니다.
- `./build` 폴더에 빌드 결과물을 위치시키도록 하세요. 그리고 `.gitignore`에 `build/`를 추가하세요.
_이유:_
> 취향대로 이름을 지으세요. `dist`도 괜찮습니다. 하지만 팀 내에서 일관성을 지키도록 하세요. 그 안에 들어가는 것은 대부분 생성되거나(번들되거나, 컴파일되거나, 트랜스파일되거나) 옮겨진 파일일 가능성이 높습니다. 당신이 생성할 수 있다면, 당신의 팀원도 생성할 수 있을 것이므로 그 파일들을 원격 저장소에 올릴 필요는 없습니다. 특별히 필요한 경우가 아니라면요.
- 파일명과 디렉토리명을 위해 `PascalCase`나 `camelCase`를 사용하세요. `PascalCase`는 컴포넌트용으로만 사용하세요.
- `CheckBox` 컴포넌트를 위해서 `CheckBox/index.js`나 `CheckBox.js`를 사용하세요. 하지만 장황한 `CheckBox/Checkbox.js` 혹은 `checkbox/CheckBox.js`는 사용하지 **마세요**.
- 이상적으로는, `index.js`에서 디폴트로 내보내는 모듈의 이름이 디렉토리의 이름과 일치해야 합니다.
_이유:_
> 그러면 부모 폴더만 그냥 간단히 불러와도 당신이 받게 될 컴포넌트나 모듈이 뭔지 예상할 수 있게 됩니다.
<a name="code-style"></a>
## 7. 코드 스타일

<a name="code-style-check"></a>
### 7.1 코드 스타일 가이드라인
- 새로운 프로젝트에는 stage-2 이상의 현대적인 JavaScript 문법을 사용하세요. 오래된 프로젝트에서는 프로젝트를 현대화(modernize)할 계획이 없다면 일관성을 위해 기존 문법을 유지하세요.
_이유:_
> 이것은 모두 당신에게 달렸습니다. 우리는 새로운 문법의 장점을 사용하기 위해 트랜스파일러를 사용합니다. stage-2는 약간의 사소한 수정이 있을 수는 있지만, 결국 스펙의 일부가 될 겁니다.
- 빌드 프로세스에 코드 스타일 체크를 포함하세요.
_이유:_
> 빌드를 깨트리는 건 당신의 코드에 스타일을 강제하는 방법 중 하나입니다. 그렇게 하면 당신이 코드 스타일을 유지하는 데에 더 진지해질 겁니다. 클라이언트, 서버 양 쪽 모두에 하세요. [더 읽기](https://www.robinwieruch.de/react-eslint-webpack-babel/)
- 코드 스타일을 강제하기 위해 [ESLint](http://eslint.org/)를 사용하세요.
_이유:_
> 꼭 `eslint`를 선택할 필요는 없지만 우리는 `eslint`를 선호합니다. `eslint`는 더 많은 룰을 지원하고, 규칙을 설정하거나 추가할 수도 있습니다.
- 우리는 JavaScript에 [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)를 사용합니다. ([더 읽기](https://www.gitbook.com/book/duk/airbnb-javascript-guidelines/details)) 프로젝트나 팀이 요구하는 JavaScript 스타일 가이드를 사용하세요.
- [FlowType](https://flow.org/)을 사용할 때, 우리는 [ESLint용 Flow type 스타일 체크 룰](https://github.com/gajus/eslint-plugin-flowtype)을 사용합니다.
_이유:_
> Flow는 약간의 문법을 제공합니다. 그 문법 역시 특정한 코드 스타일을 따르고 체크되어야할 필요가 있습니다.
- 코드 스타일 체크로부터 파일이나 폴더를 제외하기 위해 `.eslintignore`를 사용하세요.
_이유:_
> 스타일 체크로부터 몇 몇 파일을 제외할 때마다 `eslint-disable` 주석으로 코드를 더럽게 만들 필요가 없습니다.
- 풀 리퀘스트를 만들기 전에 `eslint` 비활성화 주석을 제거하세요.
_이유:_
> 코드를 짜는 동안 로직에 집중하기 위해서 스타일 체크를 비활성화 하는 건 일상적인 일입니다. 그냥 `eslint-disable` 주석을 비활성화하는 걸 잊지말고 규칙을 따르세요.
- 작업의 크기에 따라서 `//TODO` 주석을 사용하거나 이슈를 새로 만드세요.
_이유:_
> 그렇게 하면 당신 스스로나 다른 사람들에게 작은 작업(함수 리팩토링 혹은 주석 업데이트)을 상기시킬 수 있습니다. 조금 더 큰 작업에 대해서는 린트 규칙에 의해 강제되는 `//TODO(#3456)` 같은 주석을 사용하세요. 번호는 이슈 번호를 뜻합니다.
- 항상 주석이 코드 변경점과 관련이 있도록 유지하세요. 주석처리된 코드 블록은 제거하세요.
_이유:_
> 당신의 코드는 최대한 읽기 좋게 만드세요. 집중을 할 수 없게 만드는 것은 무엇이든 지워야합니다. 만약 함수를 리팩토링한다면, 예전 코드를 주석처리하지 말고 제거하세요.
- 부적절하거나 웃기는 주석, 로그, 네이밍을 피하세요.
_이유:_
> 빌드 프로세스에서 그것들을 제거할 수도 있지만, 때때로 당신의 소스 코드가 다른 회사/클라이언트에게 넘어가서 곤란한 상황이 될 수도 있습니다.
- 의미있게 구별이 되도록 검색이 잘되는 이름을 짓고 줄임말을 피하세요. 함수의 경우, 길고 설명적인 이름으로 지으세요. 함수의 이름은 동사이거나 동사구여야 하며, 의도를 전달해야합니다.
_이유:_
> 소스코드를 더 자연스럽고 가독성 좋게 만듭니다.
- 함수를 내림차 순으로 정렬해두세요. 고레벨의 함수는 최상단에 위치해야 하며 저레벨의 함수는 아래에 위치해야 합니다.
_이유:_
> 소스코드를 더 자연스럽고 가독성 좋게 만듭니다.
<a name="enforcing-code-style-standards"></a>
### 7.2 표준 코드 스타일 강제하기
- 서로 다른 에디터들 사이에서도 일관적인 코딩 스타일을 정의하고 유지하도록 돕는 [.editorconfig](http://editorconfig.org/) 파일을 사용하세요.
_이유:_
> EditorConfig 프로젝트는 코딩 스타일을 정의하는 파일 포맷과, 에디터가 파일 포맷을 읽을 수 있도록 도와주고 정의한 스타일을 고수하는 텍스트 에디터 플러그인들의 모음으로 정의됩니다. EditorConfig 파일은 가독성이 좋고 버전 컨트롤 시스템과도 잘 동작합니다.
- 코드 스타일 에러를 표시해주는 에디터를 사용하세요. 이미 사용하고 있는 ESLint 설정과 함께 [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier)와[eslint-config-prettier](https://github.com/prettier/eslint-config-prettier)를 사용하세요. [더 읽기](https://github.com/prettier/eslint-config-prettier#installation)
- Git hook을 고려해보세요.
_이유:_
> Git hook은 개발자의 생산성을 크게 끌어올립니다. 빌드를 깨트릴 걱정 없이 스테이징이나 프로덕션에 변경 사항을 만들고 커밋, 푸시를 할 수 있습니다. [더 읽기](http://githooks.com/)
- precommit hook과 함께 Prettier를 사용하세요.
_이유:_
> `prettier` 자체는 매우 강력하지만, 매번 코드를 포맷팅 할 때마다 npm 태스크로 실행하는 건 별로 생산적이지 않습니다. 이 부분에서는 `lint-staged`나 `husky`가 편리합니다. 설정하는 방법은 `lint-staged`([여기](https://github.com/okonet/lint-staged#configuration))나 `husky`([여기](https://github.com/typicode/husky))에서 더 알아보세요.
<a name="logging"></a>
## 8. 로깅

- 프로덕션에서 클라이언트 사이드의 로깅은 피하세요.
_이유:_
> 아마 빌드 프로세스가 로깅 함수를 지워버리겠지만, 그럼에도 불구하고 코드 스타일 체크를 통해 `console.log`가 있으면 경고하도록 만드세요.
- 프로덕션에서 가독성 좋은 로그를 남기세요. 프로덕션 모드에서 [winston](https://github.com/winstonjs/winston) 이나 [node-bunyan](https://github.com/trentm/node-bunyan) 같은 로깅 라이브러리를 사용하는 것이 이상적입니다.
_이유:_
> 이렇게하면 로그 색상, 타임스탬프, 매일 반복되는 로그 파일 출력 등의 요소 덕분에 트러블 슈팅이 덜 고통스럽습니다. [더 읽기](https://blog.risingstack.com/node-js-logging-tutorial/)
<a name="api"></a>
## 9. API
<a name="api-design"></a>

### 9.1 API 설계
_이유:_
> 우리가 RESTful 인터페이스를 명확하게 구성해서 개발하도록 강제하기 때문에 팀 멤버나 고객들이 간편하고 일관적으로 사용할 수 있습니다.
_이유:_
> 일관성과 단순함의 부족은 통합 및 유지보수 비용을 크게 상승시킬 수도 있습니다. 이것이 `API 설계`가 이 문서에 포함되어있는 이유입니다.
- 우리는 대부분 리소스 지향(resource-oriented) 설계를 따릅니다. 리소스 지향 설계는 세 개의 큰 요소(리소스, 콜렉션, URL)를 가집니다.
- 리소스는 데이터를 가지고, 중첩되며, 리소스를 조작할 수 있는 메소드가 존재합니다.
- 리소스의 그룹은 콜렉션이라고 부릅니다.
- URL은 리소스 혹은 콜렉션의 온라인 위치를 식별합니다.
_이유:_
> 이것은 개발자들(당신의 주 API 사용자들을 포함)에게 매우 잘 알려져있는 설계입니다. 가독성과 사용 편의성을 제외하더라도, 범용적인 라이브러리와 커넥터를 작성할 수 있습니다. 심지어 API가 뭔지 모르더라도 말이죠.
- URL에는 케밥 케이스(kebab-case)를 사용하세요.
- 쿼리 스트링이나 리소스 필드의 파라미터로는 카멜 케이스(camelCase)를 사용하세요.
- URL 내부 리소스의 이름은 복수의 케밥 케이스를 사용하세요.
- 콜렉션을 가리키는 URL의 네이밍에는 항상 복수 명사를 사용하세요. 예: `/users`
_이유:_
> 기본적으로, 더 읽기 쉽고 URL을 일관성있게 유지시킬 수 있습니다. [더 읽기](https://apigee.com/about/blog/technology/restful-api-design-plural-nouns-and-concrete-names)
- 소스 코드에서는 복수형을 변수나 프로퍼티로 변환할 때 `List` 접미사를 사용하세요.
_이유_:
> 복수형은 URL에는 좋지만 소스 코드에서는 식별하기가 어려워 에러의 원인이 될 수 있습니다.
- 항상 콜렉션에서 시작해 식별자에서 끝나는 단일 컨셉을 사용하세요.
```
/students/245743
/airports/kjfk
```
- 이런 URL은 피하세요.
```
GET /blogs/:blogId/posts/:postId/summary
```
_이유:_
> 이건 리소스가 아니라 프로퍼티를 가리키는 겁니다. 프로퍼티는 파라미터로 넘겨 응답(Response)을 정리할 수 있습니다.
- 리소스 URL에서 동사는 제거하세요.
_이유:_
> 각각의 리소스 작업에 동사를 사용하면 엄청난 양의 URL 리스트가 생기는 건 금방입니다. 또한 패턴에 일관성이 없어 개발자들이 배우기 어렵게 만듭니다. 게다가 우리는 동사를 좀 다른 용도로 사용할 겁니다.
- 리소스가 아닌 것들을 위해 동사를 사용하세요. 이 경우, API는 어떠한 리소스도 돌려주지 않습니다. 대신, 특정 동작(Operation)을 수행하고 그 결과를 반환합니다. **이것은 CRUD(create, retrieve, update and delete)가 아닙니다!**
```
/translate?text=Hallo
```
_이유:_
> CRUD 용도로 우리는 `리소스` 혹은 `콜렉션` URL에 HTTP 메소드를 사용하기 때문입니다. 우리가 말하고 있는 동사는 실제로는 `컨트롤러` 입니다. 보통은 이런 걸 개발할 일이 별로 없습니다. [더 읽기](https://byrondover.github.io/post/restful-api-guidelines/#controller)
- 요청 본문(Request body)과 응답 타입은 JSON이며, 일관성을 유지하기 위해서 `JSON` 프로퍼티 이름으로 `camelCase`를 사용하세요.
_이유:_
> 이건 JavaScript 프로젝트 가이드라인입니다. 때문에, JSON을 생성하는 프로그래밍 언어 뿐만 아니라 JSON을 파싱하는 프로그래밍 언어도 JavaScript일거라 가정합니다.
- 리소스는 객체 인스턴스 혹은 데이터베이스 레코드와 비슷한 단일 개념이지만, 리소스 이름에 테이블 명을 사용하거나 프로퍼티 이름으로 컬럼 명을 사용하지 마세요.
_이유:_
> API의 용도는 데이터베이스 스키마를 공개하는 것이 아니라 리소스를 노출하는 것입니다.
- 재강조합니다. 리소스를 네이밍할 때 URL에는 명사만 사용하고 기능적인 측면을 설명하려고 하지마세요.
_이유:_
> 리소스 URL에는 오직 명사만 사용하고, `/addNewUser`나 `/updateUser` 같은 끝점은 피하세요. 또한 리소스 동작을 파라미터로 보내지마세요.
- HTTP 메소드를 사용해 CRUD의 기능적 측면을 나타내세요.
_방법:_
> `GET`: 리소스의 표현을 가져오기 위해 사용합니다.
> `POST`: 새로운 리소스나 서브 리소스를 만들기 위해 사용합니다.
> `PUT`: 존재하는 리소스를 업데이트하기 위해서 사용합니다.
> `PATCH`: 존재하는 리소스를 업데이트하기 위해 사용합니다. 오직 제공된 필드만 업데이트하고 다른 것들은 그대로 놔둡니다.
> `DELETE`: 존재하는 리소스를 삭제하기 위해서 사용합니다.
- 중첩된 리소스는 URL에서의 관계를 이용하세요, 예를 들어, 직원과 회사를 연결하기 위해 `id`를 사용하세요.
_이유:_
> 이것은 리소스를 탐색 가능하도록 만드는 자연스러운 방법입니다.
_방법:_
> `GET /schools/2/students ` , 2번 학교의 모든 학생들의 리스트를 가져옵니다.
> `GET /schools/2/students/31` , 2번 학교에 속한 31번 학생의 구체적인 정보를 가져옵니다.
> `DELETE /schools/2/students/31` , 2번 학교에 속한 31번 학생을 삭제합니다.
> `PUT /schools/2/students/31` , 31번 학생의 정보를 업데이트 합니다. PUT은 콜렉션 말고 리소스 URL에만 사용하세요.
> `POST /schools` , 새로운 학교를 만들고 만들어진 학교의 구체적인 정보를 반환합니다. 콜렉션 URL에 POST 메소드를 사용하세요.
- 버전을 위해서 `v` 접두어와 함께 간단한 서수(ordinal number)를 사용하세요(v1, v2). 가장 높은 스코프를 가지도록 URL의 가장 왼쪽에 위치시키세요.
```
http://api.domain.com/v1/schools/3/students
```
_이유:_
> 다른 서드 파티를 위해 API를 공개한 경우, Breaking change를 포함하는 API 업그레이드는 그 API를 사용하는 프로덕트나 서비스 또한 깨트릴 수 있습니다. URL에 버전을 사용해서 그런 사건을 예방하세요. [더 읽기](https://apigee.com/about/blog/technology/restful-api-design-tips-versioning)
- 응답 메시지는 스스로 설명할 수 있어야 합니다. 좋은 에러 메시지 응답은 다음과 같이 생겼습니다.
```json
{
"code": 1234,
"message": "뭔가 안 좋은 일 발생",
"description": "세부 정보"
}
```
혹은 Validation 에러의 경우,
```json
{
"code": 2314,
"message": "Validation 실패",
"errors": [
{
"code": 1233,
"field": "email",
"message": "유효하지 않은 이메일"
},
{
"code": 1234,
"field": "password",
"message": "비밀번호가 제공되지 않음"
}
]
}
```
_이유:_
> 개발자들이 당신의 API를 사용해 어플리케이션을 개발한 뒤에, 트러블 슈팅을 할 때나, 이슈를 해결하는 중요한 상황에서 그들은 잘 설계된 에러에 의존합니다.
_주의: 보안상의 예외 메시지는 가능한 일반적으로 만드세요. 예를 들어, '틀린 비밀번호' 대신에 '틀린 유저명 혹은 비밀번호'라는 답변으로 대신하여 유저명은 실제로 맞고 비밀번호만 잘못되었다는 사실을 유저에게 무의식적으로 알리지 않을 수 있습니다._
- **모든 것이 잘 동작한다**, **클라이언트 앱이 뭔가 잘못했다**, 혹은 **API가 뭔가 잘못했다** 여부를 표현하기 위해, 응답으로 아래의 8가지 상태 코드만 사용하세요.
_목록:_
> `200 OK`는 `GET`, `PUT` 혹은 `POST` 요청이 성공했음을 표현합니다.
> `201 Created`는 새로운 인스턴스가 생성되었을 때 보냅니다. `POST` 메소드를 이용해 새로운 인스턴스를 생성하면 `201` 상태 코드를 반환합니다.
> `304 Not Modified` 응답은 수신자가 캐시 데이터를 가지고 있을 때 정보 교환을 최소화하기 위해서 사용됩니다.
> `400 Bad Request` 응답은 요청이 처리되지 않았을 때, 서버가 클라이언트가 요청하는 게 무엇인지 알 수 없을 때 사용합니다.
> `401 Unauthorized`는 요청에 유효한 자격증명이 없을 때, 필요한 자격증명으로 다시 요청해야하는 경우 사용합니다.
> `403 Forbidden`는 서버가 요청을 이해했으나, 승인은 거절한다는 의미입니다.
> `404 Not Found`는 요청한 리소스를 찾을 수 없음을 나타냅니다.
> `500 Internal Server Error`는 요청이 유효하나, 서버가 예상치 못한 상황으로 인해 요청을 실행하지 못했음을 나타냅니다.
_이유:_
> 대부분의 API 공급자들은 HTTP 상태 코드의 작은 부분집합만 사용합니다. 예를 들어 구글의 GData API는 단 10개의 상태 코드를 사용하고, 넷플릭스는 9개, Digg는 겨우 8개를 사용합니다. 물론, 이러한 응답들은 추가적인 정보를 담고있는 본문을 포함합니다. HTTP 상태 코드는 70개 이상 존재합니다. 그러나, 대부분의 개발자는 70개 모두를 기억하지는 못합니다. 그러므로 만약 당신이 일반적으로 쓰이지 않는 상태 코드를 사용한다면, 어플리케이션 개발자들은 개발을 하다말고 위키피디아로 가서 당신이 뭘 말하려고 했는지 알아볼 것입니다. [더 읽기](https://apigee.com/about/blog/technology/restful-api-design-what-about-errors)
- 응답에 리소스의 숫자를 제공하세요.
- `limit`과 `offset` 파라미터를 허용하세요.
- 노출되는 리소스 데이터의 양도 고려해야 합니다. API 사용자는 항상 리소스의 모든 필드를 필요로 하지 않습니다. 쉼표로 구분된 필드 목록을 포함하는 필드 쿼리 파라미터를 사용하세요.
```
GET /student?fields=id,name,age,class
```
- 페이지네이션, 필터링 및 정렬은 처음부터 모든 리소스에 대해 지원될 필요는 없습니다. 필터링과 정렬을 지원하는 리소스에 대해 문서를 작성하세요.
<a name="api-security"></a>
### 9.2 API 보안
다음과 같이, 몇 가지 기본적인 보안 모범사례가 존재합니다.
- 보안 연결(HTTPS) 없이 "Basic" 인증은 사용하지 마세요. 인증 토큰은 URL로 전달(`GET /users/123?token=asdf....`)되어서는 안됩니다.
_이유:_
> 토큰 혹은 유저 ID 및 비밀번호는 네트워크를 통해 명확한 텍스트로 전달됩니다. (Base64 인코딩을 사용하지만, Base64는 디코딩이 가능하죠.) Basic 인증 방식은 안전하지 않습니다. [더 읽기](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication)
- 토큰은 다음처럼 모든 요청에 대해 Authorization 헤더를 사용해서 전달되어야 합니다. `Authorization: Bearer xxxxxx, Extra yyyyy`
- 인증 코드(Authorization Code)는 유효기간이 짧아야 합니다.
- 안전하지 않은 데이터 교환을 피하기 위해 HTTP 요청에 응답하지 않음으로써 TLS 요청이 아닌 요청을 거부하세요. HTTP 요청에 `403 Forbidden`으로 응답하세요.
- 요청 제한을 고려해보세요.
_이유:_
> API를 봇이 시간 당 몇 천 건의 요청을 보내는 위협에서 보호하세요. 빠른 속도로 요청 제한을 구현하는 걸 고려해야합니다.
- HTTP 헤더를 적절하게 설정하면, 웹 어플리케이션의 보안을 유지하는데 도움이 됩니다. [더 읽기](https://github.com/helmetjs/helmet)
- API는 받은 데이터를 표준 형식으로 변환하거나 거부해야 합니다. 잘못되거나 빠진 데이터에 대한 세부 정보와 함께 400 Bad Request를 돌려주세요.
- REST API로 교환된 모든 데이터는 API에 의해 유효한지 검사되어야 합니다.
- JSON을 직렬화(Serailize)하세요.
_이유:_
> JSON 인코더의 중요한 관심사는 브라우저 혹은 Node.js 서버에서 임의의 JavaScript 원격 코드의 실행을 막는 것입니다. 브라우저에서 사용자가 제공한 데이터를 실행할 수 없도록 적절한 JSON 인코더를 사용해서 사용자가 제공한 데이터를 적절하게 인코딩하는 것은 중요합니다.
- Content-Type을 검증하고, Content-Type 헤더로 거의 `application/*.json`을 사용하세요.
_이유:_
> 예를 들머, `application/x-www-form-urlencoded` MIME 타입을 받아들이게 되면 공격자들이 폼을 만들고 간단한 POST 요청을 일으키는 것을 허용하게 됩니다. 서버는 절대 Content-Type을 가정해서는 안됩니다. Content-Type 헤더의 부재 혹은, 예상치 못한 Content-Type 헤더는 서버에서 `4XX` 응답으로 거부해야 합니다.
- API 보안 체크리스트 프로젝트를 살펴보세요. [더 읽기](https://github.com/shieldfy/API-Security-Checklist)
<a name="api-documentation"></a>
### 9.3 API 문서화
- [README.md 템플릿](./README.sample.md)의 `API 참조` 섹션을 채우세요.
- 샘플 코드를 첨부해서 API 인증 방법을 기술하세요.
- 요청 타입(HTTP METHOD)을 포함해 URL(경로만 포함, 루트 URL 제외) 구조를 설명하세요.
각각의 끝점(Endpoint)에 대해서 다음과 같은 사항이 포함되어야 합니다.
- URL 파라미터가 존재한다면 다음과 같이 URL 섹션에 언급된 이름에 따라 URL 파라미터를 명시합니다.
```
Required: id=[integer]
Optional: photo_id=[alphanumeric]
```
- 요청 타입이 POST인 경우 동작하는 예제를 제공하세요. URL 파라미터 규칙도 여기에 적용됩니다. 필수와 옵션 섹션을 구분하세요.
- 응답 성공: 상태 코드는 어떻게 되어야 하며, 돌려주는 데이터는 어떤 건가요? 아래처럼 하면 요청의 결과를 알아야할 필요가 있을 때 유용합니다.
```
Code: 200
Content: { id : 12 }
```
- 응답 에러: 대부분의 끝점에 대한 요청은 비인증 접근부터 잘못된 파라미터까지, 다양한 방법으로 실패할 수 있습니다. 이런 에러들은 명시되어야 합니다. 너무 반복적일 수도 있지만, 가정을 하지 않게 하는데 도움이 됩니다. 예를 들어,
```json
{
"code": 403,
"message": "인증 실패",
"description": "유효하지 않은 유저명 혹은 비밀번호"
}
```
- API 설계 도구를 사용하세요. 좋은 문서화에 도움을 주는 다양한 오픈소스가 있습니다. [API Blueprint](https://apiblueprint.org/)나 [Swagger](https://swagger.io/) 같은 것들 말이죠.
<a name="licensing"></a>
## 10. 라이센스

사용 권한이 있는 리소스만 사용해야 합니다. 라이브러리를 사용할 때는 MIT, Apache 혹은 BSD 라이센스를 찾아야한다는 걸 기억하세요. 또한 당신이 라이브러리를 수정해야 한다면, 라이센스 세부정보를 잘 살펴보세요. 저작권이 있는 이미지나 비디오는 법적 문제를 야기할 수 있습니다.
---
Sources:
[RisingStack Engineering](https://blog.risingstack.com/),
[Mozilla Developer Network](https://developer.mozilla.org/),
[Heroku Dev Center](https://devcenter.heroku.com),
[Airbnb/javascript](https://github.com/airbnb/javascript),
[Atlassian Git tutorials](https://www.atlassian.com/git/tutorials),
[Apigee](https://apigee.com/about/blog),
[Wishtack](https://blog.wishtack.com)
Icons by [icons8](https://icons8.com/)
================================================
FILE: README-pt-BR.md
================================================
[中文版](./README-zh.md)
| [日本語版](./README-ja.md)
| [한국어](./README-ko.md)
| [РУССКИЙ](./README-ru.md)
| [ENGLISH](./README.md)
| [Persian/فارسی](./README-ir.md)
[<img src="./images/elsewhen-logo.png" width="180" height="180">](https://www.elsewhen.com/)
# Padrões de Projeto · [](http://makeapullrequest.com)
> Enquanto desenvolver um novo projeto é apenas diversão para você, manter esse projeto pode ser um dos piores pesadelos para outra pessoa.
> Isso aqui é uma lista dos padrões que encontramos, coletamos e escrevemos que (para nós) funcionam realmente bem com a maioria dos projetos JavaScript aqui na [elsewhen](https://www.elsewhen.com).
> Se você quer compartilhar alguma prática que considera importante ou acha que alguma das coisas descritas aqui deve ser removida, [Sinta se a vontade para nos dizer](http://makeapullrequest.com).
🔥 [Confira](https://github.com/elsewhencode/react-redux-saucepan) nosso [react redux projeto base](https://github.com/elsewhencode/react-redux-saucepan) em Flow com hot reloading e server-side rendering.
<hr>
- [Padrões de Projeto · ](#padr%C3%B5es-de-projeto-middot-prs-s%C3%A3o-bem-vindoshttpmakeapullrequestcom)
- [1. Git](#1-git)
- [1.1 Algumas regras do Git](#11-algumas-regras-do-git)
- [1.2 Git workflow](#12-git-workflow)
- [1.3 Escrevendo boas mensagens de commit](#13-escrevendo-boas-mensagens-de-commit)
- [2. Documentação](#2-documenta%C3%A7%C3%A3o)
- [3. Ambientes](#3-ambientes)
- [3.1 Ambientes de dev consistentes:](#31-ambientes-de-dev-consistentes)
- [3.2 Dependências consistentes:](#32-depend%C3%AAncias-consistentes)
- [4. Dependências](#4-depend%C3%AAncias)
- [5. Testes](#5-testes)
- [6. Nomes e estrutura](#6-nomes-e-estrutura)
- [7. Estilo de código](#7-estilo-de-c%C3%B3digo)
- [7.1 Alguns padrões de estilo de código](#71-alguns-padr%C3%B5es-de-estilo-de-c%C3%B3digo)
- [7.2 Force o code style](#72-force-o-code-style)
- [8. Logging](#8-logging)
- [9. API](#9-api)
- [9.1 API design](#91-api-design)
- [9.2 API security](#92-api-security)
- [9.3 API documentation](#93-api-documentation)
- [10. Licença](#10-licen%C3%A7a)
<a name="git"></a>
## 1. Git

<a name="some-git-rules"></a>
### 1.1 Algumas regras do Git
Essas são algumas regras do Git para manter em mente:
- Trabalhe em uma feature branch.
_Por que?:_
> Porque desse jeito todo o código é criado isolado em uma branch específica ao invés de poluir a branch principal com trabalho em progresso. Isso vai permitir você abrir vários pull requets sem confusão. Você pode continuar com uma branch em progresso sem correr o risco de quebrar a branch principal com código instável. [Leia mais sobre...](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow)
- Sempre comece uma nova branch a partir da `develop`
_Por que?_
> Desse jeito você pode garantir que o código na master vai estar sempre pronto para fazer build sem problemas e poderá ser usado a qualquer momento para fazer releases (isso pode ser exagero para alguns projetos).
- Nunca dê push direto na `develop` ou `master`. Sempre faça Pull Requests.
_Por que?_
> Isso permite outros membros do time saberem que você terminou uma feature. Também possibilita code review e dicussões sobre o código que está prestes a ser introduzido no code base.
- Atualize sua `develop` local e faça rebase interativo antes de subir sua feature e abrir um Pull Request.
_Por que?_
> Rebase vai fazer um merge do branch destino do pull request e aplicar os commits que você tem localmente no topo da história sem criar um commit de merge (assumindo que não tem conflitos). Como resultado você tem uma história limpa no seu repositório. [Leia mais sobre ...](https://www.atlassian.com/git/tutorials/merging-vs-rebasing)
- Resolva os conflitos enquanto faz o rebase e antes de abrir o Pull Request.
- Delete feature branches, local e remoto, depois de realizar o merge.
_Por que?_
> Vai reduzir sua lista de branches removendo branches mortas. Vai garantir que você apenas faça o merge de uma branch uma única vez. Feature branches só devem existir enquanto o código ainda está em progresso.
- Antes de fazer um Pull Request, tenha certeza que sua feature branch está fazendo build corretamente e passando em todos os testes (incluindo os padrões de estilo de código).
_Por que?_
> Você está prestes a colocar seu código em uma branch estável. Se sua feature branch faz algum teste falhar, a chance é alta de que você vai quebrar o build na branch destino. Você também precisa conferir o code style antes de fazer um Pull Request. Isso contribui para legibilidade e reduz a chance de algum problema de formatação is para o code base com as outras alterações.
- Faça uso desse [`.gitignore`](./.gitignore).
_Por que:_
> É uma lista que já contém arquivos de sistemas que não devem ser enviados para o seu repositório remoto. E também exclui pastas de configuração e os arquivos comumente usado por editores e obviamente, também, pastas de dependência.
- Proteja (Bloqueie) a `develop` e `master`.
_Por que?_
> Protege suas branchs que devem, em teoria, estarem prontas para irem para produção de receberem códigos e mudanças irreversíveis. Leia mais sobre... [Github](https://help.github.com/articles/about-protected-branches/), [Bitbucket](https://confluence.atlassian.com/bitbucketserver/using-branch-permissions-776639807.html) e [GitLab](https://docs.gitlab.com/ee/user/project/protected_branches.html)
<a name="git-workflow"></a>
### 1.2 Git workflow
Devido a maioria dos motivos listados acima, nos usamos [Feature-branch-workflow](https://www.atlassian.com/git/tutorials/comparing-workflows#feature-branch-workflow) com [Interactive Rebasing](https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing) e alguns pontos do [Gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows#gitflow-workflow) (nomeação e ter uma develop branch). Os principais passos são:
- Em um projeto novo, inicialize o git na pasta do projeto. **Para qualquer features/changes ignore esse passo**.
```sh
cd <pasta do projeto>
git init
```
- Checkout para uma nova branch feature/bug-fix.
```sh
git checkout -b <branchname>
```
- Faça as alterações.
```sh
git add <arquivo1> <arquivo2> ...
git commit
```
_Por que?_
> `git add <arquivo1> <arquivo2> ...` - Você deve add apenas arquivos com mudanças pequenas e concisas.
> `git commit` Abrirá o editor, o que permite você separar o titulo da mensagem.
> Leia mais sobre na _seção 1.3_.
_Dica:_
> Você poderia usar `git add -p`, o que te daria a chance de revisar todas as mudanças introduzidas, uma a uma, e decidir se inclui ou não naquele commit.
- Sincronize com as ultimas alterações no repositório remoto.
```sh
git checkout develop
git pull
```
_Por que?_
> Isso vai permitir que você lide com os conflitos na sua máquina local enquanto você faz o rebase (posteriormente) ao invés de criar um pull request com conflitos.
- Atualize sua feature branch com as ultimas alterações da develop usando rebase iterativo.
```sh
git checkout <branchname>
git rebase -i --autosquash develop
```
_Por que?_
> Você pode usar --autosquash para comprimir todos os seus commits em um único commit. Ninguém quer commits de desenvolvimento de uma feature na develop. [Leia mais sobre...](https://robots.thoughtbot.com/autosquashing-git-commits)
- Se você não tem conflitos, pule esse passo. Se você tem conflitos, [resolva-os](https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/) e continue onrebase.
```sh
git add <file1> <file2> ...
git rebase --continue
```
- Push sua branch. Rebase vai alterar a história, então você precisa usar `-f` para forçar a mudança no branch remoto. Se tem mais alguém trabalhando na mesma branch, use o comando `--force-with-lease`.
```sh
git push -f
```
_Por que?_
> Quando você faz rebase, você está mudando a história na sua feature branch. Então o git ira rejeitar seu `git push`. Para passar por isso você precisa usar -f ou --force flag. [Leia mais sobre...](https://developer.atlassian.com/blog/2015/04/force-with-lease/)
- Abra um Pull Request.
- Pull request deve ser aceito, mergiado e fechado por quem estiver revisando.
- Delete seu branch local se tiver terminado.
```sh
git branch -d <nome do branch>
```
Para remover todos os branchs que não existem no repositório remoto:
```sh
git fetch -p && for branch in `git branch -vv --no-color | grep ': gone]' | awk '{print $1}'`; do git branch -D $branch; done
```
<a name="writing-good-commit-messages"></a>
### 1.3 Escrevendo boas mensagens de commit
Ter um bom padrão para criar commits e se atentar a ele faz com que trabalhar com Git e colaborar com outros seja muito mais fácil. Aqui estão algumas boas práticas ([fonte](https://chris.beams.io/posts/git-commit/#seven-rules)):
- Separe o assunto e a mensagem com uma nova linha entre eles.
_Por que?_
> Git é inteligente o suficiente para identificar a primeira linha do seu commit como um resumo. Na verdade, se você tentar shortlog, ao invés de git log, você vai ver uma longa lista de mensagens de commits, com apenas o id e o resumo do commit.
- Máximo de 50 caracteres para o assunto e 72 para a mensagem.
_Por que?_
> Commits devem ser objetivos e claros, não é o momento para ser verboso. [Leia mais sobre...](https://medium.com/@preslavrachev/what-s-with-the-50-72-rule-8a906f61f09c)
- Capitalize a linha do assunto.
- Não use um ponto para finalizar a linha do assunto.
- Use [imperative mood](https://en.wikipedia.org/wiki/Imperative_mood) na linha do assunto.
_Por que?_
> É melhor que o commit diga o que vai acontecer no projeto depois daquele commit do que o que o que aconteceu dentro do commit em si. [Lei mais sobre...](https://news.ycombinator.com/item?id=2079612)
* Use a mensagem para explicar **o que** e **porque** ao invés de **como**.
<a name="documentation"></a>
## 2. Documentação

- Use esse [template](./README.sample.md) para `README.md`, sinta-se a vontade para adicionar seções que achar necessárias.
- Para projetos com mais de um repositório adicione todos os respctivos links nos `README.md` de todos os projetos.
- Mantenha o `README.md` enquanto o projeto evolui.
- Comente seu código. Tente sempre deixar claro o que uma grande parte do código tem a intenção de fazer.
- Se existe alguma referência em relação a forma como você resolveu o problema ou uma discussão em aberto, adicione os links.
- Não use comentários como desculpa para fazer um código ruim. Mantenha seu código limpo.
- Não use código limpo como uma desculpa para não fazer nenhum comentário.
- Mantenha apenas os comentários relevantes enquanto o código evolui.
<a name="environments"></a>
## 3. Ambientes

- Defina ambientes de `desenvolvimento`, `testes` e `produção` separados.
_Por que?_
> Diferentes informações, dados, tokens, APIs, portas etc... podem ter que ser diferentes em cada ambiente. Você provavelmente vai querer isolar seu ambiente de `desenvolvimento` para fazer chamadas fake para a API que retornará dados previsíveis, tornando tanto os testes automatizados quanto os manuais muito mais facéis. Ou você pode querer ativar o Google Analytics apenas em `produção` e etc... [Leia mais sobre...](https://stackoverflow.com/questions/8332333/node-js-setting-up-environment-specific-configs-to-be-used-with-everyauth)
* Carregue suas configurações específicas de deploy de variáveis de ambiente e nunca as adicione no seu codebase como constantes, [veja aqui um exemplo](./config.sample.js).
_Por que?_
> Você terá tokens, senhas e outras informações sigilosas nessa configuração. Sua configuração deve ser corretamente separada da sua aplicação como se seu codebase pudesse se tornar público a qualquer momento.
_Como?_
> Arquivos `.env` para manter suas variáveis e então adicione-o ao `.gitignore` para ser excluído. Ao invés, commit um `.env.example` que servirá de modelo para outros desenvolvedores. Para produção, você deve setar suas variáveis no jeito padrão. [Leia mais sobre...](https://medium.com/@rafaelvidaurre/managing-environment-variables-in-node-js-2cb45a55195f)
* É recomendável validar suas variáveis de ambiente antes de inicializar sua aplicação. [De uma olhada nesse exemplo](./configWithTest.sample.js) usando `joi` para validar os valores.
_Por que?_
> Pode salvar todos de horas de "dor de cabeça".
<a name="consistent-dev-environments"></a>
### 3.1 Ambientes de dev consistentes:
- Defina sua versão do node em `engines` no `package.json`.
_Por que?_
> Permite que todos saibem em qual versão o projeto funciona. [Leia mais sobre...](https://docs.npmjs.com/files/package.json#engines)
- Adicionalmente, use `nvm` e crie um arquivo `.nvmrc` na raíz do seu projeto. Não se esqueça de menciona-lo na sua documentação.
_Por que?_
> Qualque pessoa que usar `nvm` pode apenas rodar `nvm use` para trocar para a versão correta. [leia mais sobre...](https://github.com/creationix/nvm)
- É uma boa ideia criar um script `preinstall` para conferir as versões do node e do npm.
_Por que?_
> Algumas dependências podem falhar quando instaladas por versões mais recentes do NPM.
- Use Docker se puder.
_Por que?_
> Te dará um ambiente estável durante todo o workflow. Sem muita necessidade de lidar com dependências e configurações. [leia mais sobre...](https://hackernoon.com/how-to-dockerize-a-node-js-application-4fbab45a0c19)
- Use local modules ao invés de modules instalados globalmente.
_Por que?_
> Você estará compartilhando suas dependências com os outros ao invés de esperar que eles a tenham instalado globalmente.
<a name="consistent-dependencies"></a>
### 3.2 Dependências consistentes:
- Garanta que seus colegas de equipe obtenham exatamente a mesma versão de dependências que você.
_Por que?_
> Porque você quer que se código tenha o mesmo comportamento em qualquer máquina de desenvolvimento [leia mais sobre...](https://medium.com/@kentcdodds/why-semver-ranges-are-literally-the-worst-817cdcb09277)
_Como?_
> Use `package-lock.json` a partir do `npm@5`
_E se eu não tenho npm@5?_
> Uma alternativa pode ser o `Yarn` e não se esqueça de mencionar o seu uso no `README.md`. Seu lock file e o `package.json` devem manter as mesmas versões após cada atualização. [leia mais sobre...](https://yarnpkg.com/en/)
_E se eu não gosto do nome `Yarn`?_
> Que pena. Para versões antigas do `npm`, use `—save --save-exact` quando instalando novas dependências e criando um `npm-shrinkwrap.json` antes de publicar. [Leia mais sobre...](https://docs.npmjs.com/files/package-locks)
<a name="dependencies"></a>
## 4. Dependências

- Acompanhe seus pacotes disponíveis atualmente: e.g., `npm ls --depth=0`. [Leia mais sobre...](https://docs.npmjs.com/cli/ls)
- Confira se algum dos seus pacotes não está em uso ou se tornou irrelevante: `depcheck`. [Leia mais sobre...](https://www.npmjs.com/package/depcheck)
_Por que?_
> Você pode estar fazendo o bundle final ficar maior com bibliotecas não usadas. Identifique essas bibliotecas não usadas e se livre delas.
- Antes de começar a usar uma dependência, confira o quanto ela é usada pela comunidade: `npm-stat`. [Leia mais sobre...](https://npm-stat.com/)
_Por que?_
> Maior uso geralmente significa mais contribuidores, o que leva a deduzir que possui melhor manutenção, o que tudo isso junto leva a concluir que bugs serão encontrados mais facilmente e resolvidos rapidamente.
- Antes de usar uma dependência, confira se possui uma versão madura o suficiente com um grande número de pessoas mantendo: e.g., `npm view async`. [Leia mais sobre...](https://docs.npmjs.com/cli/view)
_Por que?_
> Ter muitos contribuidores não var ser tão efetivo se os mantenedores não fizerem os merge fixes e patches rápido.
- Se você precisa de uma dependência menos conhecida, discuta com o time antes de usa-la.
- Sempre tenha certeza que sua aplicação funciona com a ultima versão das dependências: `npm outdated`. [Leia mais sobre...](https://docs.npmjs.com/cli/outdated)
_Por que?_
> Atualização de dependência as vezes possuem 'breaking changes'. Sempre confira a descrição da nova versão sempre que sair, isso faz com que lidar com os possíveis problemas seja mais fácil. Use uma dessas ferramentas maneiras, como: [npm-check-updates](https://github.com/tjunnone/npm-check-updates).
- Confira problemas de segurança com a dependência que você quer adicionar, e.g., [Snyk](https://snyk.io/test?utm_source=risingstack_blog).
<a name="testing"></a>
## 5. Testes

- Tenha um ambiente the `test` se necessário
_Por que?_
> Embora algumas vezes testes end to end em `produção` possam parecer suficientes, existem algumas exceções: Um exemplo é que você não vai querer colocar dados analíticos em `produção` e assim poluir o dashboard de alguém com dados de teste. Outro exemplo é que sua API pode ter algumas limitações enquanto em `produção` e chamadas de teste depois de uma certa quantidade.
- Coloque os arquivos de teste junto com os arquivos a serem testados usando a convenção `*.test.js` ou `*.spec.js` para nomear os arquivos, como `moduleName.spec.js`.
_Por que?_
> Você não quer ter que navegar em várias pastas para achar um teste unitário. [Leia mais sobre...](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc)
* Coloque seus arquivos de testes adicionais em uma pasta separada para evitar confusão.
_Por que?_
> Alguns arquivos de testes não tem nenhuma relação com qualquer outro arquivo. Você deve coloca-los em uma pasta fácil de ser encontrada pelos outros desenvolvedores do time, como por exemplo: Uma pasta `__test__`. Essa nomeação é padrão e reconhecida pela maioria de frameworks de teste de JavaScript.
* Escreva código testável, evite efeitos colaterais (side effects), escreva funções puras
_Por que?_
> Você vai querer testar uma regra de negócio como uma unidade separada. Voce tem que "minimizar o impacto de aleatoriedade e processos não determinísticos no seu código". [Leia mais sobre...](https://medium.com/javascript-scene/tdd-the-rite-way-53c9b46f45e3)
> Uma função pura é uma função que sempre retorna o mesmo valor para uma entrada específica. Por outro lado, uma função impura é uma função que pode ter efeitos colaterais e depender de condições externas para retornar algum valor. Isso reduz a capacidade de prever o que o código vai realizar. [Leia mais sobre...](https://hackernoon.com/structure-your-javascript-code-for-testability-9bc93d9c72dc)
* Use uma checagem de tipo estática
_Por que?_
> As vezes você vai precisar de checagem de tipo estática. O que também aumenta a regidibilidade e legibilidade do seu código. [Leia mais sobre...](https://medium.freecodecamp.org/why-use-static-types-in-javascript-part-1-8382da1e0adb)
- Rode os testes localmente antes de abrir um pull request para `develop`.
_Por que?_
> Você não quer ser a pessoa a fazer com que a branch com código pronto para produção pare de funcionar. Rode seus teste depois que fizer `rebase` e antes de fazer push para sua feature branch.
- Documente seus testes incluindo instruções importantes em uma seção no arquivo `README.md`.
_Por que?_
> Vai ser de muita ajuda para outros desenvolvedores, DevOps, QA ou qualquer um que tiver a sorte de trabalhar com seu código.
<a name="structure-and-naming"></a>
## 6. Nomes e estrutura

- Organize seus arquivos considerando feature / páginas / componentes. E também, coloque os arquivos de teste próximos à implementação..
**Ruim**
```
.
├── controllers
| ├── product.js
| └── user.js
├── models
| ├── product.js
| └── user.js
```
**Bom**
```
.
├── product
| ├── index.js
| ├── product.js
| └── product.test.js
├── user
| ├── index.js
| ├── user.js
| └── user.test.js
```
_Por que?_
> Ao invés de uma longa lista de arquivos você estará criando pequenos modulos encapsulando responsabilidades e seus respectivos testes. Fica muito mais fácil de se navegar e as coisas podem ser facilmente encontradas.
- Use uma pasta com o nome `./config` e **não** crie arquivos de configuração diferente para cada ambiente.
_Por que?_
> Quando você distribuí as configurações em arquivos com propósitos diferentes (database, API e etc); Coloca-los em uma pasta com o nome fácil de reconhecer como `config` faz sentido. Apenas se lembre de não criar arquivos de configuração diferentes para cada ambiente. Isso não escala, cada novo deploy diferente que se faz necessário, novos nomes de ambientes são criados.
> Valores para serem usados por arquivos de configuração devem ser providos através de variáveis de ambiente. [Leia mais sobre...](https://medium.com/@fedorHK/no-config-b3f1171eecd5)
* Coloque seus scripts em uma pasta nomeada `./scripts`. Isso vale para `bash` e `node`.
_Por que?_
> É bem provável que você vai acabar com mais de um script, build de produção, build de dev, database feeders, database sync e etc...
- Direcione os arquivos de output do build em uma pasta nomeada `./build`. Adicione `build/` no `.gitignore`.
_Por que?_
> Dê o nome que você achar conveniente, `dist` também é uma boa opção. Mas tenha a certeza de manter isso consistente com os projetos do time. Os arquivos que vão para essa pasta são gerados automaticamente (bundled, compiled, transpiled) ou movidos automaticamente para lá. O que você pode gerar, qualquer um no time deve ser capaz de gerar também, então não faz nenhum sentido comitar isso para o repositório. A não ser que você realmente queira muito fazer isso.
<a name="code-style"></a>
## 7. Estilo de código

<a name="code-style-check"></a>
### 7.1 Alguns padrões de estilo de código
- Use stage-2 e sintaxe moderna de JavaScript nos seus novos projetos. Para os projetos antigos, mantenha a consistência, a não ser que modernizar o projeto seja o objetivo.
_Por que?_
> É claro, isso só depende de você. Nós usamos transpilers para tirar vantagem de novas sintaxes. stage-2 é bem provável de se tornar parte da especificação em alguma revisão.
- Inclua alguma conferência automática de padrão de código no seu build.
_Por que?_
> Quebrar o build é uma forma de forçar os padrões de código. Evite que não seja levado a sério. Faça isso tanto para o backend quanto para o front. [Leia mais sobre...](https://www.robinwieruch.de/react-eslint-webpack-babel/)
- Use [ESLint - Pluggable JavaScript linter](http://eslint.org/) para garantir que os padrões serão seguidos.
_Por que?_
> Nós simplesmente preferimos `eslint`, você não precisa necessariamente o usar. Ele tem mais regras suportadas, a possibilidade de configura-las e criar regras customizadas.
- Nós usamos [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript) para JavaScript, [Leia mais sobre](https://www.gitbook.com/book/duk/airbnb-javascript-guidelines/details). Escolha os padrões necessário para seu projeto.
- Usamos [Flow type style check rules for ESLint](https://github.com/gajus/eslint-plugin-flowtype) ao usar [FlowType](https://flow.org/).
_Por que?_
> Flow usa algumas sintaxes que também precisam de seguir um padrão.
- Use `.eslintignore` para excluir os arquivos que devem ser ignorados pelas regras.
_Por que?_
> Você não precisa poluir seu código com comentários como `eslint-disable` toda vez que quiser desabilitar alguma regra em um certo arquivo.
- Remova todos `eslint-disable` antes de fazer um pull request.
_Por que?_
> É normal desabilitar o `eslint` para focar na lógica de uma parte do código. Apenas se lembre de remover o `eslint-disable` quando terminar.
- Dependendo do tamanho da task, use comentários com `//TODO:` para ajudar na criação de novas tasks para o backlog.
_Por que?_
> Você vai deixar um lembrete para os outros, e para você mesmo, de pequenas tarefas ou correções (como refatorar uma função ou atualizar um comentário). Para tarefas maiores escreva `//TODO(#3456)` fazendo referência ao ticket aberto no backlog para aquela task.
* Sempre faça comentários relevantes. Delete código morto ou comentado.
_Por que?_
> Você deve prezar pela legibilidade do seu código, então se livre de qualquer distração possível no código. Se você refatorou uma função, não deixe a antiga lá apenas comentada, delete-a.
* Evite comentários irrelevantes, engraçados ou ofensivos.
_Por que?_
> Mesmo que seu processo de build possa remove-los, as vezes seu código pode ser pego por alguém diferente, uma empresa terceirizada ou um chefe de outra área e isso pode não ser tão tranquilo.
* Use nomes com significados, fáceis de pesquisar e sem abreviações para suas variáveis ou funções. O nome de uma função deve ser um verbo ou uma frase e precisa de deixar claro a sua intenção.
_Por que?_
> Faz com que o seu código seja mais legível e natual.
<a name="enforcing-code-style-standards"></a>
### 7.2 Force o code style
- Use o arquivo [.editorconfig](http://editorconfig.org/) para ajudar a definir e manter a consistência de estilo de código entre diferentes editores e IDE.
_Por que?_
> O EditorConfig consiste em um arquivo para edição de estilo de código e declaração de plugins para habilitar o editor a ler os arquivos em um determinado formato e formatá-los de acordo com o esperado. EditorConfig são fáceis de ler e funcionam muito bem com sistemas de controle de versão.
- Configure seu editor para alertar sobre erros de estilo de código. Use [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) e [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) com seu arquivo ESLint já existente. [Leia mais sobre...](https://github.com/prettier/eslint-config-prettier#installation)
- Considere usar Git Hooks.
_Por que?_
> Git hooks aumentam de forma expressiva a produtividade do desenvolvedor. Faça alterações, commit e push sem o medo de quebrar o código pronto para produção. [Leia mais sobre...](http://githooks.com/)
- Use Prettier com o precommit hook.
_Por que?_
> O `prettier` por si só pode ser bem poderoso porém, não é muito produtivo rodar uma npm task sozinha toda hora só para formatar o código. É então que o `lint-staged` (e o `husky`) entram em ação. Leia mais sobre como configurar o `lint-staged` [aqui](https://github.com/okonet/lint-staged#configuration) e sobre o `husky` [aqui](https://github.com/typicode/husky).
<a name="logging"></a>
## 8. Logging

- Evite console logs no client-side em produção
_Por que?_
> Mesmo que o seu processo de compilação possa (e deva) se livrar deles, certifique-se de que seu lint de código avise sobre os console logs restantes.
- Crie logs de produção legíveis. O ideal é utilizar bibliotecas de log em produção (como, por exemplo [winston](https://github.com/winstonjs/winston) ou
[node-bunyan](https://github.com/trentm/node-bunyan)).
_Por que?_
> Ele torna sua solução de problemas mais agradável com sistema de cores, data e hora, registra em um arquivo além do console e até mesmo pode atualizar o arquivo diariamente. [saiba mais...](https://blog.risingstack.com/node-js-logging-tutorial/)
<a name="api"></a>
## 9. API
<a name="api-design"></a>

### 9.1 API design
_Por que?_
> Queremos promover o desenvolvimento de RESTful interfaces bem construídas, fazendo com que o consumo por clientes e pelo time seja simples e consistente.
_Por que?_
> Falta de consistência e simplicidade podem aumentar de forma expressiva os custos de manutenção e integração. E por isso `API design` está nesse documento.
- Devemos seguir o padrão orientado a recursos. O qual tem 3 principais fatore: recursos, coleções, e URLs.
- Um recurso possui dados, gets aninhados, e methods para permitir operações.
- Um grupo de recursos é chamado coleção.
- URL identifica a localização online de um recurso ou coleção.
_Por que?_
> Esse é um padrão muito bem conhecido por desenvolvedores (os principais consumidores de sua API). Fora o fato de ser fácil de usar e ler, permite-nos escrever bibliotecas genéricas e conectores sem ao menos precisar saber sobre o que a API é.
- use kebab-case para as URLs.
- use camelCase para os parâmetros na query string ou campo de recursos.
- use o plural do kebab-case nome dos recursos na URL.
- Sempre use o plural para nomear algum recurso na URL ou coleção: `/users`.
_Por que?_
> Basicamente, é melhor para ler e torna a URL mais consistente. [Leia mais sobre...](https://apigee.com/about/blog/technology/restful-api-design-plural-nouns-and-concrete-names)
- No código fonte, converta plurais para variáveis e propriedades com uma lista de sufixos.
_Por que?_
> Plural é interessante para URLs mas no código é muito sucetível a erros.
- Sempre use um conceito singular que comece com a coleção e termine com um identificador:
```
/students/245743
/airports/kjfk
```
- Evite URLs como:
```
GET /blogs/:blogId/posts/:postId/summary
```
_Por que?_
> Isso não está apontando para um recurso mas, para uma propriedade. Você pode passar a propriedade como um parâmetro para encurtar a resposta.
- Matenha as URLs de recursos sem verbos.
_Por que?_
> Porque se você usar verbos para cada operação em um recurso você vai acabar com uma lista enorme de URLs e nenhum padrão consistente, o que torna difícil para desenvolvedores lerem. Além disso, nos usamos verbos para outra situação.
- Use verbos para 'não recursos'. Nesse caso, sua API não retorna nenhum recurso. Ao invés, você executa uma operação que retorna um resultado. Essas **não são** operações de um CRUD (criar, ler, atualizar, e deletar):
```
/translate?text=Hallo
```
_Por que?_
> Porque para CRUD nos usamos os métodos HTTP nos `recursos` ou `coleções`. Os verbos que estamos falando são literalmente `Controllers`. Você geralmente não chega a desenvolver muito deles. [Leia mais sobre...](https://byrondover.github.io/post/restful-api-guidelines/#controller)
- Use `camelCase` para as propriedades no `JSON` das requisições e da repostas do servidor para manter a consistência.
_Por que?_
> Esse é um padrão de projeto para JavaScript, onde a linguagem usada para gerar e parsear JSON é, em teoria, JavaScript.
- Mesmo que um recurso seja um conceito singular, similar à uma instância ou registro do banco de dados, você não deve usar `nome_da_tabela` para o nome de um recurso e `nome_da_coluna` para a propriedade de um recurso.
_Por que?_
> Porque sua intenção é expor os recursos, não detalhes do schema do seu banco de dados.
- Novamente, apenas use substantivos quando nomeando a URL de um recurso e não tente explicar a funcionalidade.
_Por que?_
> Apenas use substantivos nos recursos na URL, evite coisas como `/addNewUser` ou `/updateUser`. Também, evite enviar operações sobre os recursos como parâmetros.
- Explicite as operações de CRUD usando funcionalidades do métodos HTTP:
_Como:_
> `GET`: Para obter/recuperar um recurso.
> `POST`: Para criar um novo recurso ou sub-recurso.
> `PUT`: Para atualizar recursos existentes.
> `PATCH`: Para atualizar recursos existentes. Atualiza apenas os campos enviados deixando as outras propriedades como eram.
> `DELETE`: Para deletar um recurso existente.
* Para recursos aninhados, use a relação entre eles e a URL. Por exemplo, usando `id` para se referir a um usuário específico.
_Por que?_
> Esse é um jeito natural de tornar os recursos fáceis de explorar.
_Como?_
> `GET /schools/2/students` , Deve obter a lista de estudantes da escola com ID 2.
> `GET /schools/2/students/31` , Deve obter os detalhes do estudante 31, que pertence a escola 2.
> `DELETE /schools/2/students/31` , Deve deletar o estudante 31, que pertence a escola 2.
> `PUT /schools/2/students/31` , Deve atualizar as informações do estudante 31, Use PUT apenas para URL de recursos, não para coleções.
> `POST /schools` , Deve criar uma nova escola e retornar os detalhes da nova escola criada. Use POST em URL de coleções.
* Use um simples número ordinal para a versão com o prefixo `v` (v1, v2). Coloque a versão à esquerda de todos URL da api:
```
http://api.domain.com/v1/schools/3/students
```
_Por que?_
> Quando suas APIs são públicas, atualizar a API com alguma mudança que quebra o funcionamento antigo (Breaking Change) pode levar ao mal funcionamento de vários produtos e serviços que dependem da sua API. Usnado versões na URL você previne isso de acontecer. [Leia mais sobre...](https://apigee.com/about/blog/technology/restful-api-design-tips-versioning)
- Messagens das respostas devem ser auto descritivas. Uma boa mensagem de erro deve ser algo parecido com:
```json
{
"code": 1234,
"message": "Algo de errado aconteceu",
"description": "Mais detalhes"
}
```
Ou para validação de erros:
```json
{
"code": 2314,
"message": "Validação Falhou",
"errors": [
{
"code": 1233,
"field": "email",
"message": "Email inválido"
},
{
"code": 1234,
"field": "password",
"message": "Senha em branco"
}
]
}
```
_Por que?_
> Desenvolvedores dependem de erros bem descritivos em momentos críticos quando eles estão com dificuldades resolvendo problemas da aplicação que eles construíram usando sua API.
_Nota: Mantenha mensagens relacionadas a exceções de segurança o mais genéricas possível. Por exemplo, ao invés de 'Senha incorreta', você pode responder dizendo 'Usuário ou senha inválidos' para que não vaze informações sobre dados corretos que não deveriam ser conhecido por terceiros._
- Use códigos de status para enviar e descrever suas respostas ao invés de **tudo funcionou corretamente**,
**App do cliente fez algo errado** ou A **API fez algo errado**.
_Quais?_ > `200 OK` resposta de sucesso para requisições `GET`, `PUT` ou `POST`.
> `201 Created` para quando uma nova instância é criada. Criar uma nova instância usando `POST` deve retornar o código de status `201`.
> `204 No Content` resposta representa sucesso porém não tem nenhum conteúdo para ser enviado na resposta. Use quando operações com `DELETE` são bem sucedidas.
> `304 Not Modified` resposta para minimizar informações trafegadas quando o "requerente" já possui os dados em cache.
> `400 Bad Request` para quando a requisição não foi processada, como por exemplo quando o servidor não compreendeu o conteúdo da requisição.
> `401 Unauthorized` para quando a requisição não possui credenciais suficientes para ser executada.
> `403 Forbidden` siginifica que o servidor entendeu a requisição mas se recusa a realizá-la.
> `404 Not Found` indica que o recurso da requisição não foi encontrado.
> `500 Internal Server Error` indica que a requisição foi recebida mas devida à algum erro interno a requisição não pode ser completada.
_Por que?_
> A maioria das APIs fornecem um algum subconjunto de códigos de status HTTP. Por exemplo, a API do Google GData usa apenas 10 códigos, Netflix usa 9, e Digg, apenas 8. Evidente que essas requisições possuem dados com informações adicionais. Existem mais de 70 códigos de status HTTP. De qualquer forma, A maioria dos desenvolvedores não tem todos memorizados. Então se você escolher códigos que não são muito comuns pode assustar e repelir desenvolvedores de usar sua API. [Leia mais sobre...](https://apigee.com/about/blog/technology/restful-api-design-what-about-errors)
* Forneça o número total de recursos na sua resposta.
* Aceite `limit` e `offset` como parâmetros.
* A quantidade de dados que os recursos expõem deve ser levado em consideração. O consumidor da API nem sempre precisa ter uma representação completa do recurso. Use `fields` na query string para filtrar propriedades a serem enviadas:
```
GET /student?fields=id,name,age,class
```
* Paginação, filtragem e ordenação não precisam ser suportadas inicialmente para todos os recursos. Documente os recursos que oferecem tais funcionalidades.
<a name="api-security"></a>
### 9.2 API security
Algumas boas práticas básicas de segurança:
- Não use autenticação básica a não ser sob uma conexão HTTPS. Tokens de autenticação não devem ser enviados na URL: `GET /users/123?token=asdf....`
_Por que?_
> Porque tokens ou ID de usuário e senha são enviados pela rede como texto (encoded como base64, mas base64 é um encoding reversível), o esquema básico de autenticação não é seguro [Leia mais sobre...](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication)
- Tokens devem ser enviados fazendo uso do header `Authorization` em todas as requisições: `Authorization: Bearer xxxxxx, Extra yyyyy`.
- Códigos de autorização devem ter "tempo de vida curto".
- Rejeite qualquer requisição não-TLS não respondendo nenhuma requisição HTTP para evitar vazamento de dados. Apenas responda `403 Forbidden`.
- Considere usar Limite de requisições.
_Por que?_
> Para proteger sua API de requisições maliciosas repetidas milhares de vezes por hora. Você deve considerar implementar Limite de requisições o mais cedo possível.
- Configurando os headers HTTP corretamente pode te ajudar a protejer sua aplicação web. [Leia mais sobre...](https://github.com/helmetjs/helmet)
- Sua API deve converter os dados recebidos para sua forma canônica ou rejeita-los. Retrone status `400 Bad Request` com detalhes sobre os de dados errados ou faltantes.
- Todos os dados trocados com a API REST devem ser validados pela API.
- Serialize seu JSON.
_Por que?_
> Uma das principais preocupações lidando com JSON encoders é previnir JavaScript malicioso de ser executado no browser... Ou, se você está usando `node.js`, no servidor. É vital usar JSON corretamente serializados para evitar a execução de código enviado como input pelo broswer.
- Valide o content-type e na maioria dos casos use `application/*json` (Content-Type header).
_Por que?_
> Por exemplo, aceitando `application/x-www-form-urlencoded` mime type permite que alguém com má intenções crie um form e execute uma simple requisição POST. O servidor nunca deve tentar adivinhar o Content-Type. A falta do Content-Type ou um Content-Type inesperado deve resultar no servidor recusando a request com um erro `4XX` na resposta.
- Confira o checklist de segurança para um projeto de API. [Leia mais sobre...](https://github.com/shieldfy/API-Security-Checklist)
<a name="api-documentation"></a>
### 9.3 API documentation
- Complete a seção `API Reference` no [README.md Template](./README.sample.md) para sua API.
- Descreva os métodos de autentic
gitextract_hg0vvobc/ ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README-ir.md ├── README-it.md ├── README-ja.md ├── README-ko.md ├── README-pt-BR.md ├── README-ru.md ├── README-zh.md ├── README.md ├── README.sample.md ├── config.sample.js └── configWithTest.sample.js
Condensed preview — 15 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (325K chars).
[
{
"path": ".gitignore",
"chars": 1312,
"preview": "### Node ###\n\n# Logs\nlogs\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Optional npm cache directory\n.npm\n\n# Depende"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3214,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "CONTRIBUTING.md",
"chars": 304,
"preview": "# Contributing to Project Guidelines\n\n### No guidelines here :D, hit us with your PR.\n**Working on your first Pull Reque"
},
{
"path": "LICENSE",
"chars": 1096,
"preview": "The MIT License (MIT)\nCopyright (c) 2018 Elsewhen https://www.elsewhen.com\nPermission is hereby granted, free of charge,"
},
{
"path": "README-ir.md",
"chars": 49996,
"preview": "[中文版](./README-zh.md)\n| [日本語版](./README-ja.md)\n| [한국어](./README-ko.md)\n| [Русский](./README-ru.md)\n| [Português](./READM"
},
{
"path": "README-it.md",
"chars": 50009,
"preview": "[中文版](./README-zh.md)\n| [日本語版](./README-ja.md)\n| [한국어](./README-ko.md)\n| [English](./README.md)\n| [Русский](./README-ru."
},
{
"path": "README-ja.md",
"chars": 26533,
"preview": "[中文版](./README-zh.md)\n| [ENGLISH](./README.md)\n| [한국어](./README-ko.md)\n| [РУССКИЙ](./README-ru.md)\n| [Português](./READM"
},
{
"path": "README-ko.md",
"chars": 27092,
"preview": "[ENGLISH](./README.md)\n| [中文版](./README-zh.md)\n| [日本語版](./README-ja.md)\n| [РУССКИЙ](./README-ru.md)\n| [Português](./READ"
},
{
"path": "README-pt-BR.md",
"chars": 41501,
"preview": "[中文版](./README-zh.md)\n| [日本語版](./README-ja.md)\n| [한국어](./README-ko.md)\n| [РУССКИЙ](./README-ru.md)\n| [ENGLISH](./README."
},
{
"path": "README-ru.md",
"chars": 44522,
"preview": "[中文版](./README-zh.md)\n| [日本語版](./README-ja.md)\n| [한국어](./README-ko.md)\n| [English](./README.md)\n| [Português](./README-p"
},
{
"path": "README-zh.md",
"chars": 22284,
"preview": "[ENGLISH](./README.md) |\n[日本語版](./README-ja.md) |\n[한국어](./REAMDE-ko.md) |\n[РУССКИЙ](./README-ru.md) |\n[Português](./READ"
},
{
"path": "README.md",
"chars": 43292,
"preview": "[中文版](./README-zh.md)\n| [日本語版](./README-ja.md)\n| [한국어](./README-ko.md)\n| [Русский](./README-ru.md)\n| [Português](./READM"
},
{
"path": "README.sample.md",
"chars": 3098,
"preview": "<img src=\"./images/logo.sample.png\" alt=\"Logo of the project\" align=\"right\">\n\n# Name of the project · [![Build St"
},
{
"path": "config.sample.js",
"chars": 465,
"preview": "// required environment variables\n[\n 'NODE_ENV',\n 'PORT'\n].forEach((name) => {\n if (!process.env[name]) {\n throw n"
},
{
"path": "configWithTest.sample.js",
"chars": 941,
"preview": "const joi = require('joi')\n\nconst envVarsSchema = joi.object({ \n NODE_ENV: joi.string()\n .valid(['development', 'pr"
}
]
About this extraction
This page contains the full source code of the elsewhencode/project-guidelines GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 15 files (308.3 KB), approximately 100.7k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.