Naming Convention - vonix-id/styleguide GitHub Wiki
There are only 2 hard problems in Computer Science:
0. cache invalidation
1. naming things
2. off-by-1 errors
Table of Contents:
-
Naming Convention
- Why Naming Conventions are Important
- Content Sections
- General Naming Conventions
- SwiftUI
- Java and/or Kotlin
- REST API Request or Response
-
REST API Design
- HTTP Methods
- Use Nouns instead of Verbs
- Plural Nouns are Preferable to Singular
- Represent Complex Parameters with a Query String
- Avoid Using a Forward Slash at the End of the URL
- Use a Forward Slash to Set a Relationship
- Use a Hyphen to Increase URL Friendliness
- Avoid Using Underscores in URLs
- Use Lowercase Letters for Resources
- Avoid Using File Extensions
- Custom HTTP Headers
- Unit Tests
- Database
A programmer is always said to write clean codes, where naming has to be appropriate so that for any other programmer it acts as an easy way out to read the code. At a smaller level, this seems meaningless but think of the industrial level where it becomes necessary to write clean codes in order to save time for everyone who reads your code.
Data structures are meant to last much longer than application logic.
Once they are set, changing them may break dependent applications. This is even more reason to name things properly before the first use.
-
Indicate Purpose
โ val date = getDate() // expiration date โ val expirationDate = getDate()
-
Avoid Disinformation
โ List<Account> accountList = new LinkedList<>() // might not be a list โ List<Account> accounts = new LinkedList<>()
-
Add Meaning
// what kind of data? โ fun processData(data: String) { ... } // clear meaning โ fun processUserData(data: String) { ... }
-
Searchable
// generation year, month, day, hour, minute, second โ int genymdhms // clear and pronounceable name โ int generationTimestamp
-
Add Context
โ fun save(name: String) { ... } โ fun saveCustomerName(n: String) { ... }
-
Find a Balance
class EfficientStringHandlingController { ... }
The following are some guidelines on structuring a markdown document.
-
Start each page with a
#
heading for the title, followed by##
and###
for subheadings. Example:# General Guidelines ## Clarity Over Brevity Use descriptive names that clearly convey purpose, even if longer. ## Avoid Abbreviations Prefer full words unless abbreviations are widely recognized.
-
Use fenced code blocks for code examples. Specify the language (e.g.
swift
) to enable syntax highlighting. Example:struct LoginView: View { var body: some View { Text("Login") } }
-
Use ordered lists for step-by-step instructions and unordered lists for general points. Example:
- Use descriptive file names. - Follow a logical hierarchy.
Generally follows the same guidelines from Microsoft.
- โ๏ธ DO NOT capitalize each word in so-called closed-form compound words. Treat a closed-form compound word as a single word.
โ๏ธ๏ธ Good | โ๏ธ Bad |
---|---|
callback |
CallBack , callBack
|
canceled |
cancelled |
email |
EMail , eMail
|
endpoint |
EndPoint , endPoint
|
filename |
FileName , fileName
|
gridline |
GridLine , gridLine
|
hashtable |
HashTable , hashTable
|
id |
ID |
indexes |
indices |
metadata |
MetaData , metaData
|
ok |
OK |
pi |
PI |
placeholder |
PlaceHolder , placeHolder
|
username |
UserName ,userName
|
whitespace |
WhiteSpace ,whiteSpace
|
- โ๏ธ๏ธ DO choose easily readable identifier names.
For example, a property named
HorizontalAlignment
is more English-readable thanAlignmentHorizontal
. - โ๏ธ๏ธ DO favor readability over brevity.
For example, the property name
CanScrollHorizontall
is better thanScrollableX
(an obscure reference to the X-axis). - โ๏ธ DO NOT use underscores, hyphens, or any other nonalphanumeric characters.
- โ๏ธ DO NOT use Hungarian notation.
- โ๏ธ AVOID using identifiers that conflict with keywords of widely used programming languages.
- โ๏ธ๏ธ DO use semantically interesting names rather than language-specific keywords for type names.
For example,
GetLength
is a better name thanGetInt
.
- โ๏ธ DO NOT use abbreviations or contractions as part of identifier names.
For example, use
GetWindow
rather thanGetWin
. - โ๏ธ DO NOT use any acronyms that are not widely accepted, and even if they are, only when necessary.
- When appropriate, use well-known acronyms to replace lengthy phrase names.
For example, use
UI
for User Interface, orOLAP
for On-line Analytical Processing.
- Two letter acronyms (like
IO
orDB
), should have the same case for both letters. For example, for PascalCase identifiers (like a class name) you might haveDBRate
instead ofDbRate
, while for a camelCase identifier (like a local variable) you might haveioChannel
. - Three letters or longer acronyms use mixed case.
For example, for PascalCase identifiers (like a class name) you might have
XmlDocument
instead ofXMLDocument
, while for a camelCase identifier (like a local variable) you might havehttpRequest
.
- โ๏ธ๏ธ DO use a name similar to the old API when creating new versions of an existing API. This helps to highlight the relationship between the APIs.
- โ๏ธ๏ธ DO prefer adding a suffix rather than a prefix to indicate a new version of an existing API. This will assist discovery when browsing documentation, or using autocomplete. The old version of the API will be organized close to the new APIs, because most browsers and autocomplete show identifiers in alphabetical order.
- โ๏ธ๏ธ CONSIDER using a brand new, but meaningful identifier, instead of adding a suffix or a prefix.
- โ๏ธ๏ธ DO use a numeric suffix to indicate a new version of an existing API, particularly if the existing name of the API is the only name that makes sense (i.e. if it is an industry standard) and if adding any meaningful suffix (or changing the name) is not a appropriate option.
- โ๏ธ DO NOT use the "Ex" (or a similar) suffix for an identifier to distinguish it from an earlier version of the same API.
This section outlines specific naming conventions for SwiftUI components to maintain consistency across the project.
-
Use
PascalCase
for view names and end withView
to indicate their type. Example:struct LoginView: View { var body: some View { Text("Login") } }
-
Use descriptive names that indicate the purpose of the modifier. Example:
extension View { func roundedCorners(_ radius: CGFloat) -> some View { self.cornerRadius(radius) } }
-
Use
PascalCase
for class and struct names, and indicate their purpose. Example:class UserViewModel: ObservableObject { @Published var username: String = "" }
-
Use descriptive names and suffix with
Key
. Example:struct CustomFontKey: EnvironmentKey { static let defaultValue: Font = .body }
-
Use
camelCase
for constants within SwiftUI files and prefix them withstatic
if they are part of a struct. Example:struct Constants { static let padding: CGFloat = 16.0 }
- Generally follows the official Kotlin coding conventions, but with minor revisions (e.g. two spaces instead of four spaces).
- Our Kotlin coding convention rules (and revisions) are defined in
detekt-config.yml
.
For boolean variables, use the prefix is
, has
, or can
:
isEnabled
hasAccess
canEdit
For DateTime variables, use the postfix At
:
createdAt
updatedAt
deletedAt
enabledAt
disabledAt
- Use the
to
prefix when converting or creating a new type (e.g.toString()
,toInt()
,toList()
). - Use the
as
prefix when casting types (e.g.List
asIterable
->asIterable()
,Cat
asAnimal
->asAnimal()
).
Use a noun and short noun phrase for the interface, then using a prefix for each implementation describing how it's implemented. e.g.:
-
List
interface, with implementations includingArrayList
(using array),LinkedList
(using linked objects), etc. -
Set
interface, with implementations includingHashSet
(using hash table),TreeSet
(using tree map), etc. -
Map
interface, with implementations includingHashMap
(using hash table),LinkedHashMap
(using linked map), etc. -
Reader
interface, with implementations includingFileReader
andStringReader
, etc. -
Truck
interface, with implementations such asDumpTruck
,TransferTruck
,CementTruck
,TestTruck
,FakeTruck
,MainTruck
, etc.
Warning
Do not suffix the name of your class implementations with Impl
(implementation) (such as TruckImpl
),
because that name is meaningless!
If you do so, we will hunt you down.
Kotlin provides the .not()
operator function used for logical negation. For example:
val isLoggedIn = false
val isNotLoggedIn = isLoggedIn.not() // isNotLoggedIn == true
val hasPermission = true
val doesNotHavePermission = !hasPermission // equivalent to hasPermission.not()
Notes:
- The
.not()
operator is equivalent to the logical NOT operator (!
) in Kotlin. - The
.not()
is considered an operator function because it follows the naming convention of having a single dot (.
) before the function name. -
In most cases, the
!
operator is preferred due to its readability, simplicity, and familiarity. - The
.not()
operator might be useful in situations where you want to emphasize the negation operation or when dealing with custom data types that overload the!
operator for different purposes.
- Should always be in JSON format.
- Use
snake_case
style[^1]. - Suffix your domain model classes with
Request
orResponse
appropriately.- e.g.
UpdateAccountRequest
andUpdateAccountResponse
. - Don't use
DTO
,JDO
,Bean
, or any other silly suffixes.
- e.g.
- Always ensure that
Request
body and all of its fields are nullable:- User might not send the correctly formatted request body.
- Fields are filled with invalid format or data types (e.g. number fields with strings, etc.).
[^1]: Starting in V2.
References:
- Deep Dive into REST API Design and Implementation Best Practices (YouTube, 12m)
- Microsoft REST API Guidelines
- RESTful API Best Practices by Spencer Schneidenbach
- Beautiful REST+JSON APIs by Les Hazlewood
- Top 5 RESTful API Design Best Practices by Vladimir Sidorenko
- REST API Best Practices and Endpoint Design Examples by Kolade Chris
- Developer Docs:
The most common methods include:
HTTP Method | CRUD Operation | Description |
---|---|---|
๐ข GET | Read | Retrieves a resource. |
๐ POST | Create | Create a new resource. |
๐ต PUT | Update | Updates an existing resource. |
๐ฃ PATCH | Update | Partially updates an existing resource. |
๐ด DELETE | Delete | Removes a resource. |
The endpoints should use nouns, signifying what each of them does.
For example, https://mysite.com/v1/posts
is better than:
https://mysite.com/v1/getPosts
https://mysite.com/v1/createPost
Using plural or singular nouns for defining resources has no any impact on how your API will work; however, there are common conventions that are used in all good RESTful APIs. One of such convention is the use of plural nouns for defining resources.
-
/users
is better than/user
-
/users/16
is better than/user/16
. -
https://mysite.com/v1/posts/123
is better thanhttps://mysite.com/v1/post/123
.
Note: avoid mixing singular and plural nouns.
In RESTful APIs, a query string (โ?โ) is commonly used for setting complex parameters to define resources. It keeps the URL short, logical, and simple. Remember that all optional parameters must be recognized through a query string.
GET /users?location=US&age=21
is better than
GET /users
GET /US-basedUsers
GET /US-basedUsersAnd21-agedUsers
A trailing forward slash (โ/โ) has no semantic meaning and can lead to confusion. That is why a forward slash should be avoided when forming the URL, even though gearheart.io/portfolio/ and gearheart.io/portfolio will be treated equally by most web frameworks and components. Furthermore, a good RESTful API will use the 301st redirect to display the page without a forward slash in the URL.
Using a forward slash for indicating a hierarchy in the URL has become a commonly used principle:
/forbes.com/technology/#5b89537f4bad
This example shows a relationship between a home page โforbes.comโ and the category โtechnology.โ
To allow users easily read your URL, use hyphens (โ-โ) or even a camel case, instead of one long line of words. In all RESTful APIs, a hyphen equates to a space:
/techcrunch.com/2017/09/24/techcrunchs-startup-battlefield-australia-joined-by-leading-aussie-names/
Taking into account that web browsers usually underline links to inform users that the URL is clickable, you should avoid using underscores ("_") to define resources. The browserโs underlining format will hide your underscore, which can confuse users.
Using uppercase letters to define resources makes the URL key sensitive, which may lead to confusion in particular situations. Using lowercase letters will ensure the correctness of the command, even if the URL was input with uppercase letters, but not vice versa:
/gearheart.io/contacts/
and /gearheart.io/Contacts/
If you use the second form to define the resource, it will not work and display an error.
RESTful APIs should not include a period to indicate a file extension. Instead, they must use the media type to determine how content should be processed. To ensure easy debugging, your API should provide the selection of media types using query parameters.
- The official RFC recommendation (RFC 6648, June 2012), recommends to not use the
X-
prefix. - Name custom headers sensibly.
- The
X-
prefix was an old RFC recommendation (RFC 2047) (e.g.x-gzip
).
In Java: MethodName_StateUnderTest_ExpectedBehavior()
There are arguments against this strategy that if method names change as part of code refactoring than test name like this should also change or it becomes difficult to comprehend at a later stage. Following are some of the example:
isAdult_AgeLessThan18_False()
withdrawMoney_InvalidAccount_ExceptionThrown()
admitStudent_MissingMandatoryFields_FailToAdmit()
In Kotlin (only for tests), method names can be more expressive by adding spaces:
fun `adult age is not less than 18`() { /*...*/ }
fun `invalid account when withdrawing money`() { /*...*/ }
fun `fail to admit students due to missing mandatory fields`() { /*...*/ }
A good article called "Database Naming Standards" by Ovid, first published in 2-March-2021.
Use snake_case
(all in lowercase).
For example, the words "under value" is different than "undervalue", with CamelCase it's Undervalue
vs. UnderValue
(but SQL is case-insensitive and thus it is identical. Underscores help reduce ambiguity and improve readability.
Use plural (customers
) as opposed to singular (customer
).
Plural names are less likely to conflict with reserved keywords. SQL has reserved word such as user
, or audit
, or role
.
- Avoid ambiguity and name column descriptively. (e.g.
celsius
as opposed totemperature
). - When possible, name foreign key columns the same as columns they refer to.
- Migration script file naming convention follows the default spec.
- Schema name should be the same as the microservice name (for easy identification).
- Version number starts at 0 and increments by 1 (do not append 0s as prefix).