Best Practices
API Design
Follow REST Conventions
Use standard HTTP methods appropriately:
| Method | Use For |
|---|---|
| GET | Retrieving data (queries, read actions) |
| POST | Creating records, executing actions |
| PUT | Full updates (replace entire record) |
| PATCH | Partial updates (modify specific fields) |
| DELETE | Removing 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
Group Related Endpoints in Modules
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