Skip to main content

Best Practices

API Design

Follow REST Conventions

Use standard HTTP methods appropriately:

MethodUse For
GETRetrieving data (queries, read actions)
POSTCreating records, executing actions
PUTFull updates (replace entire record)
PATCHPartial updates (modify specific fields)
DELETERemoving records

Use Meaningful Endpoint Names

Good endpoint names are intuitive and follow conventions:

✅ Good:
/api/sales/accounts
/api/sales/accounts/{id}/contacts
/api/support/cases/{id}/actions/resolve

❌ Avoid:
/api/getAccountData
/api/doUpdateAccount
/api/process_case_resolution

Organize your API by business domain:

Modules:
├── Sales
│ ├── Accounts
│ ├── Contacts
│ └── Opportunities
├── Support
│ ├── Cases
│ └── Knowledge Articles
└── Administration
├── Users
└── Teams

Version Your API

Use semantic versioning for API versions:

  • Minor versions (1.0 → 1.1): Backward-compatible additions
  • Major versions (1.0 → 2.0): Breaking changes

Security

Principle of Least Privilege

Grant only the minimum permissions needed. Not every user needs access to every endpoint.

✅ Good:
- Sales reps can only read/update accounts they own
- Managers can read all accounts in their team
- Admins have full access

❌ Avoid:
- All users have full CRUD access to all entities

Use Role-Based Access

Configure authorization at the endpoint level:

Action: DeleteAccount
Authorization Policy:
├── Type: Demand All
└── Roles:
├── Administrator
└── DataManager

Protect Sensitive Data

Don't expose sensitive fields through the API. Consider what data should be visible to external applications:

✅ Include:
- Account name, phone, email
- Contact job title

❌ Exclude:
- Credit card numbers
- Social security numbers
- Internal system fields

Validate All Inputs

Use pre-conditions to validate data before processing:

Pre-conditions:
├── Input Validation:
│ ├── Email format is valid
│ ├── Phone number format is valid
│ └── Required fields are present
└── Business Rules:
├── Credit limit is within approved range
└── Account status allows modification

Performance

Use Paginated Queries for Large Data Sets

Don't use Multi queries for unbounded result sets:

✅ Paginated Query (large datasets):
/api/sales/queries/accounts?page=1&pageSize=20

❌ Multi Query (returns all):
/api/sales/queries/all-accounts

Select Only Needed Columns

Don't retrieve all fields when you only need a few:

✅ Optimized:
Columns: accountid, name, telephone1

❌ Unoptimized:
Columns: * (all fields)

Consider Caching

Option sets and reference data change infrequently. UI applications can cache these responses:

// Cache option sets for 1 hour
const CACHE_DURATION = 60 * 60 * 1000;

async function getOptionSet(name) {
const cached = localStorage.getItem(`optionset_${name}`);
if (cached) {
const { data, timestamp } = JSON.parse(cached);
if (Date.now() - timestamp < CACHE_DURATION) {
return data;
}
}

const response = await fetch(`/api/optionsets/${name}`);
const data = await response.json();

localStorage.setItem(`optionset_${name}`, JSON.stringify({
data,
timestamp: Date.now()
}));

return data;
}

Optimize Data Fetcher Queries

Use efficient queries in Data Fetchers:

✅ Optimized:
Query: SELECT accountid, statecode FROM account WHERE accountid = @id

❌ Unoptimized:
Query: SELECT * FROM account WHERE accountid = @id

Maintenance

Document Your API

Use descriptions on all endpoints. Future maintainers (and UI developers) will thank you:

Action: ApproveAccount
Documentation:
├── Title: Approve Account
└── Description: Marks an account as approved for transactions.
This action updates the account status, assigns
a credit limit, and triggers notification workflows.
Can only be performed on accounts that have passed
credit check.

Test Before Publishing

Thoroughly test your API in development before publishing versions. Published versions are immutable.

Testing Checklist:

  • All endpoints return expected responses
  • Authorization policies work correctly
  • Pre-conditions validate as expected
  • Error messages are clear and helpful
  • Performance is acceptable under load

Plan for Changes

Use minor versions for backward-compatible changes, major versions for breaking changes:

Version 1.0:
└── /api/accounts (returns name, phone)

Version 1.1 (Minor - backward compatible):
└── /api/accounts (returns name, phone, email) ← Added field

Version 2.0 (Major - breaking change):
└── /api/accounts (returns accountName, primaryPhone) ← Renamed fields

Monitor Usage

Track which endpoints are used and how. This helps identify optimization opportunities and unused endpoints:

Metrics to Track:

  • Request count per endpoint
  • Response times (p50, p95, p99)
  • Error rates by endpoint
  • Most common error codes

Handle Errors Gracefully

Provide clear, actionable error messages:

✅ Good:
"Credit limit exceeds approved amount ($50,000). Contact credit
manager for higher limits."

❌ Poor:
"Validation error"
"Error code: 12345"

Summary Checklist

Before Publishing Your API

  • Endpoints follow REST conventions
  • Meaningful names for modules, entities, and actions
  • Authorization policies configured for all endpoints
  • Pre-conditions validate all business rules
  • Sensitive data is not exposed
  • Large result sets use pagination
  • Only necessary columns are selected
  • All endpoints are documented
  • Thorough testing completed
  • Error messages are clear and helpful