Naming Convention - vonix-id/styleguide GitHub Wiki

Naming Convention

There are only 2 hard problems in Computer Science:

0. cache invalidation
1. naming things
2. off-by-1 errors

Table of Contents:

Why Naming Conventions are Important

1_co8Y5tF6xAfj7AFLvNLMiA

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.

Names are Long Lived

Data structures are meant to last much longer than application logic.

Names are Contracts

Once they are set, changing them may break dependent applications. This is even more reason to name things properly before the first use.

Good Naming Rules

  1. Indicate Purpose

    โŒ val date = getDate() // expiration date
    โœ… val expirationDate = getDate()
  2. Avoid Disinformation

    โŒ List<Account> accountList = new LinkedList<>() // might not be a list
    โœ… List<Account> accounts = new LinkedList<>()
  3. Add Meaning

       // what kind of data?
    โŒ fun processData(data: String) { ... }
       // clear meaning
    โœ… fun processUserData(data: String) { ... }
  4. Searchable

       // generation year, month, day, hour, minute, second
    โŒ int genymdhms
    
       // clear and pronounceable name
    โœ… int generationTimestamp
  5. Add Context

    โœ… fun save(name: String) { ... }
    โœ… fun saveCustomerName(n: String) { ... }
  6. Find a Balance

    class EfficientStringHandlingController { ... }

Content Sections

The following are some guidelines on structuring a markdown document.

Use Headings for Structure

  • 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.

Code Blocks

  • 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")
      }
    }

Lists

  • Use ordered lists for step-by-step instructions and unordered lists for general points. Example:

    - Use descriptive file names.
    - Follow a logical hierarchy.

General Naming Conventions

Generally follows the same guidelines from Microsoft.

Capitalizing Compound Words and Common Terms

  • โŒ๏ธ 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

Word Choice

  • โœ”๏ธ๏ธ DO choose easily readable identifier names. For example, a property named HorizontalAlignment is more English-readable than AlignmentHorizontal.
  • โœ”๏ธ๏ธ DO favor readability over brevity. For example, the property name CanScrollHorizontall is better than ScrollableX (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 than GetInt.

Abbreviations

  • โŒ๏ธ DO NOT use abbreviations or contractions as part of identifier names. For example, use GetWindow rather than GetWin.
  • โŒ๏ธ 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, or OLAP for On-line Analytical Processing.

Acronyms

  • Two letter acronyms (like IO or DB), should have the same case for both letters. For example, for PascalCase identifiers (like a class name) you might have DBRate instead of DbRate, while for a camelCase identifier (like a local variable) you might have ioChannel.
  • Three letters or longer acronyms use mixed case. For example, for PascalCase identifiers (like a class name) you might have XmlDocument instead of XMLDocument, while for a camelCase identifier (like a local variable) you might have httpRequest.

Naming New Versions of Existing APIs

  • โœ”๏ธ๏ธ 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.

SwiftUI

This section outlines specific naming conventions for SwiftUI components to maintain consistency across the project.

Views

  • Use PascalCase for view names and end with View to indicate their type. Example:

    struct LoginView: View {
      var body: some View {
        Text("Login")
      }
    }

Modifiers

  • Use descriptive names that indicate the purpose of the modifier. Example:

    extension View {
      func roundedCorners(_ radius: CGFloat) -> some View {
        self.cornerRadius(radius)
      }
    }

Observable Objects and Models

  • Use PascalCase for class and struct names, and indicate their purpose. Example:

    class UserViewModel: ObservableObject {
      @Published var username: String = ""
    }

Environment Keys

  • Use descriptive names and suffix with Key. Example:

    struct CustomFontKey: EnvironmentKey {
      static let defaultValue: Font = .body
    }

Constants

  • Use camelCase for constants within SwiftUI files and prefix them with static if they are part of a struct. Example:

    struct Constants {
      static let padding: CGFloat = 16.0
    }

Java and/or Kotlin

Boolean

For boolean variables, use the prefix is, has, or can:

  • isEnabled
  • hasAccess
  • canEdit

DateTime

For DateTime variables, use the postfix At:

  • createdAt
  • updatedAt
  • deletedAt
  • enabledAt
  • disabledAt

Function Name Prefix for Converting and Casting

  • 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 as Iterable -> asIterable(), Cat as Animal -> asAnimal()).

Interfaces

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 including ArrayList (using array), LinkedList (using linked objects), etc.
  • Set interface, with implementations including HashSet (using hash table), TreeSet (using tree map), etc.
  • Map interface, with implementations including HashMap (using hash table), LinkedHashMap (using linked map), etc.
  • Reader interface, with implementations including FileReader and StringReader, etc.
  • Truck interface, with implementations such as DumpTruck, 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.

.not() Operator Function

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.

REST API Request or Response

  • Should always be in JSON format.
  • Use snake_case style[^1].
  • Suffix your domain model classes with Request or Response appropriately.
    • e.g. UpdateAccountRequest and UpdateAccountResponse.
    • Don't use DTO, JDO, Bean, or any other silly suffixes.
  • 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.

REST API Design

References:

HTTP Methods

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.

Use Nouns instead of Verbs

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

Plural Nouns are Preferable to Singular

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 than https://mysite.com/v1/post/123.

Note: avoid mixing singular and plural nouns.

Represent Complex Parameters with a Query String

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

Avoid Using a Forward Slash at the End of the URL

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.

Use a Forward Slash to Set a Relationship

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.โ€

Use a Hyphen to Increase URL Friendliness

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/

Avoid Using Underscores in URLs

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.

Use Lowercase Letters for Resources

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.

Avoid Using File Extensions

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.

Custom HTTP Headers

  • 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).

Unit Tests

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`() { /*...*/ }

Database

A good article called "Database Naming Standards" by Ovid, first published in 2-March-2021.

underscore_name instead of CamelCase

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.

Plural instead of Singular tables

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.

Column Names

  • Avoid ambiguity and name column descriptively. (e.g. celsius as opposed to temperature).
  • When possible, name foreign key columns the same as columns they refer to.

Flyway

  • 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).
โš ๏ธ **GitHub.com Fallback** โš ๏ธ