Function Naming Conventions
This guide documents function naming approaches in order of recommendation, with clear reasoning for when to use each pattern.
Quick Decision Matrix
Section titled “Quick Decision Matrix”| Your Situation | Recommended Approach |
|---|---|
| Forrst projects | URN Format ⭐ |
| Single vendor, <50 functions | Simple Dotted |
| Single vendor, 50-200 functions | Service-Grouped Dotted |
| Multi-vendor OR >200 functions | Vendor-Prefixed |
| Enterprise/compliance requirements | URN Format |
| Protobuf/schema-first design | gRPC-Style |
| AWS ecosystem integration | AWS-Style |
| Azure ecosystem integration | Azure-Style |
| Blockchain/Ethereum APIs | OpenRPC-Style |
| AI/LLM tool calling | MCP-Style |
| Frontend-driven, type-safe APIs | GraphQL-Style |
Approaches (Ranked by Recommendation)
Section titled “Approaches (Ranked by Recommendation)”1. Simple Dotted
Section titled “1. Simple Dotted”Best for: Small projects, single vendor, <50 functions
Format: {service}.{function}Examples:
orders.createorders.getusers.authenticatepayments.processPros:
- Minimal verbosity
- Familiar to JSON-RPC users
- Easy to type and read
- No configuration required
Cons:
- No vendor isolation
- No versioning strategy
- Namespace collisions in multi-vendor environments
When to use:
- Internal tools and services
- Single-team projects
- Rapid prototyping
- When simplicity trumps extensibility
2. Service-Grouped Dotted
Section titled “2. Service-Grouped Dotted”Best for: Medium projects, single vendor, 50-200 functions
Format: {domain}.{service}.{function}Examples:
commerce.orders.createcommerce.orders.getcommerce.inventory.checkidentity.users.authenticatebilling.payments.processPros:
- Logical grouping by domain
- Scales to hundreds of functions
- Clear organizational hierarchy
- Still relatively concise
Cons:
- No vendor attribution
- No explicit versioning
- Requires domain taxonomy planning
When to use:
- Growing monoliths
- Microservices within a single organization
- When you need better organization but not multi-vendor support
3. Vendor-Prefixed
Section titled “3. Vendor-Prefixed”Best for: Multi-vendor environments, >200 functions, API marketplaces
Format: {vendor}.{service}/{function}Examples:
acme.orders/createacme.orders/getacme.orders/cancelstripe.payments/chargecline.discovery/describePros:
- Clear vendor ownership
- Scales to thousands of functions
- The
/separator makes parsing unambiguous - Service grouping within vendor namespace
- Concise yet fully qualified
Cons:
- More verbose than simple dotted
- Requires vendor registry/coordination
When to use:
- Multi-vendor platforms
- Public APIs with external consumers
- API marketplaces and plugin systems
- When clear ownership attribution matters
Note: Versioning is handled at the protocol level, not in the identifier. Forrst supports native function versioning, keeping identifiers stable across versions.
4. URN Format
Section titled “4. URN Format”Best for: Forrst projects ⭐, enterprise environments, systems with extensions/plugins
Format: urn:{vendor}:{service}:{type}:{name}Examples:
# Vendor functionsurn:acme:orders:fn:createurn:acme:logistics:fn:list-shipments
# Extension functionsurn:forrst:ext:discovery:fn:describeurn:forrst:ext:deprecation:fn:list-deprecated
# System functionsurn:forrst:system:fn:pingPros:
- Self-documenting structure with semantic segments
- Type distinction (
fn,ext,system) enables routing/permissions - Clear ownership attribution (vendor segment)
- Extension clarity (which extension provides what)
- Wildcard permission patterns (
urn:vendor:*) - Written once, referenced many times (verbosity cost is minimal)
Cons:
- Most verbose option
- Requires understanding URN structure
When to use:
- Forrst projects (recommended default)
- Systems with extensions/plugins requiring type distinction
- Multi-vendor platforms needing clear ownership
- When debugging clarity matters (logs, traces, errors)
- Permission systems using prefix matching
5. gRPC-Style
Section titled “5. gRPC-Style”Best for: Protobuf/schema-first projects, strongly-typed environments
Format: /{package}.{Service}/{Method}Examples:
/acme.orders.v1.OrderService/CreateOrder/acme.orders.v1.OrderService/GetOrder/acme.payments.v1.PaymentService/ProcessPaymentPros:
- Industry-proven at massive scale (Google, etc.)
- Tight integration with Protobuf schemas
- Service grouping built-in
- Clear versioning via package
- Excellent tooling ecosystem
Cons:
- Requires Protobuf commitment
- Very verbose for simple use cases
- Service suffix (
Service) often redundant
When to use:
- Already using Protobuf/gRPC
- Need strong typing and schema validation
- High-performance binary serialization required
- Polyglot environments with code generation
6. AWS-Style
Section titled “6. AWS-Style”Best for: AWS ecosystem integration, IAM-like permission systems
Format: {service}:{Action}Examples:
s3:GetObjects3:PutObjects3:DeleteObjectdynamodb:GetItemdynamodb:PutItemlambda:InvokeFunctionec2:StartInstancesPros:
- Instantly familiar to AWS users
- Clean service:action separation
- Works well with permission/policy systems
- PascalCase actions are self-documenting
- Proven at AWS scale (thousands of actions)
Cons:
- No vendor prefix (assumes single provider)
- No explicit versioning
- PascalCase may conflict with kebab-case conventions
- Colon separator can conflict with URN schemes
When to use:
- Building AWS-integrated services
- IAM-style permission systems
- When your users already think in AWS terms
- Action-centric (vs resource-centric) APIs
Real-world patterns from AWS:
# Pattern: service:VerbNouns3:GetObjects3:ListBucketsiam:CreateUseriam:AttachRolePolicy
# Pattern: service:VerbNounPropertyec2:DescribeInstanceStatusrds:ModifyDBClusterEndpoint7. Azure-Style
Section titled “7. Azure-Style”Best for: Azure ecosystem integration, resource-centric APIs, RBAC systems
Format: {Provider}/{ResourceType}/{Action}Examples:
Microsoft.Storage/storageAccounts/readMicrosoft.Storage/storageAccounts/writeMicrosoft.Storage/storageAccounts/deleteMicrosoft.Compute/virtualMachines/startMicrosoft.Compute/virtualMachines/restartMicrosoft.Web/sites/functions/readPros:
- Resource hierarchy is explicit
- Provider namespacing (multi-vendor ready)
- Maps directly to REST resource paths
- Built for RBAC permission systems
- Clear read/write/delete/action taxonomy
Cons:
- Very verbose
- Deep nesting can get unwieldy
- Provider prefix often redundant
- Slash separator conflicts with URL paths
When to use:
- Building Azure-integrated services
- Resource-centric (vs action-centric) APIs
- Hierarchical permission systems
- When resources have clear parent/child relationships
Real-world patterns from Azure:
# Pattern: Provider/Resource/actionMicrosoft.Storage/storageAccounts/readMicrosoft.Storage/storageAccounts/listKeys/action
# Pattern: Provider/Resource/SubResource/actionMicrosoft.Storage/storageAccounts/blobServices/containers/readMicrosoft.Web/sites/config/appsettings/read
# Wildcards for permissionsMicrosoft.Storage/storageAccounts/*Microsoft.Compute/*/readAzure vs AWS comparison:
# AWS (action-centric)s3:GetObjects3:PutObject
# Azure (resource-centric)Microsoft.Storage/storageAccounts/blobServices/containers/blobs/readMicrosoft.Storage/storageAccounts/blobServices/containers/blobs/write8. OpenRPC-Style
Section titled “8. OpenRPC-Style”Best for: Blockchain/Ethereum APIs, JSON-RPC with underscore conventions
Format: {namespace}_{method}Examples:
eth_getBalanceeth_sendTransactioneth_getBlockByNumbereth_estimateGasnet_versionnet_peerCountweb3_clientVersionpersonal_signdebug_traceTransactionPros:
- Standard in Ethereum/blockchain ecosystem
- Simple flat namespace
- Underscore separator is unambiguous
- Easy to parse and validate
- Well-documented in OpenRPC spec
Cons:
- Underscore conflicts with snake_case function names
- Limited hierarchy (only one level)
- No versioning strategy
- Namespace feels like a prefix, not a category
When to use:
- Building blockchain/Ethereum-compatible APIs
- JSON-RPC APIs following OpenRPC specification
- When interoperability with Web3 tooling matters
- Simple APIs with flat structure
Real-world patterns:
# Core Ethereum methodseth_accountseth_blockNumbereth_calleth_chainIdeth_getCode
# Namespaces indicate subsystemeth_* → Core Ethereumnet_* → Network infoweb3_* → Web3 utilitiespersonal_* → Account managementdebug_* → Debugging toolstrace_* → Transaction tracing9. MCP-Style
Section titled “9. MCP-Style”Best for: AI tool integration, LLM function calling, multi-provider tool registries
Format: {vendor}__{tool} or {tool}Examples:
# Vendor-prefixed (multi-provider)github__create_issuegithub__list_reposgithub__create_pull_requestslack__send_messageslack__list_channelslinear__create_issue
# Simple (single-provider)create_fileread_filesearch_coderun_terminal_commandPros:
- Designed for AI/LLM tool calling
- Double underscore is unambiguous separator
- Vendor prefix enables multi-provider environments
- Snake_case matches Python conventions (common in AI)
- Simple tools can omit vendor prefix
Cons:
- Double underscore looks unusual
- No versioning strategy
- No service/domain grouping
- Relatively new standard (less proven)
When to use:
- Building MCP (Model Context Protocol) servers
- AI assistant tool integrations
- LLM function calling systems
- Multi-provider tool registries
Real-world patterns from MCP:
# File operationsread_filewrite_filelist_directory
# With vendor prefixgithub__search_repositoriesgithub__get_file_contentsgithub__create_or_update_file
# Naming convention- Use snake_case for tool names- Verb_noun pattern: create_issue, list_repos- Vendor prefix when multiple providers possible10. GraphQL-Style
Section titled “10. GraphQL-Style”Best for: Query languages, frontend-driven APIs, type-safe schemas
Format: {verbNoun} (camelCase)Examples:
# Queries (read operations)userusersorderByIdordersByCustomersearchProducts
# Mutations (write operations)createUserupdateUserdeleteUsercreateOrdercancelOrderprocessPayment
# Subscriptions (real-time)onOrderCreatedonPaymentProcessedonUserUpdatedPros:
- Extremely concise
- Self-documenting with verb prefixes
- Type system provides context (Query vs Mutation)
- Frontend-developer friendly
- Strong tooling ecosystem (Apollo, Relay)
Cons:
- No namespace/vendor isolation
- Relies on schema context for meaning
- Name collisions in large schemas
- Not suitable for flat RPC (needs GraphQL schema)
When to use:
- Building GraphQL APIs
- Frontend-driven API design
- When schema provides the namespace context
- Type-safe, introspectable APIs
Naming conventions:
# Queries - noun or getNounuser # Get single by IDusers # Get listuserByEmail # Get by specific field
# Mutations - verbNouncreateUserupdateUserdeleteUserassignUserRoleresetPassword
# Subscriptions - onNounVerbedonUserCreatedonOrderUpdatedonPaymentFailed
# Input typesCreateUserInputUpdateOrderInputGraphQL vs RPC comparison:
# GraphQL (schema-contextual)query { user(id: "123") { name } }mutation { createUser(input: {...}) { id } }
# RPC equivalentusers.get(id: "123")users.create(input: {...})Industry Standards Reference
Section titled “Industry Standards Reference”| Standard | Format | Primary Use Case |
|---|---|---|
| JSON-RPC 2.0 | namespace.method | Simple RPC |
| gRPC | /package.Service/Method | High-performance microservices |
| OpenRPC | namespace_method | Ethereum/blockchain APIs |
| MCP | vendor__tool | AI tool integration |
| AWS IAM | service:Action | Cloud permissions |
| Azure RBAC | Provider/Type/Action | Cloud permissions |
| GraphQL | verbNoun | Query languages |
Migration Paths
Section titled “Migration Paths”From Simple → Service-Grouped
Section titled “From Simple → Service-Grouped”# Beforeorders.createusers.get
# Aftercommerce.orders.createidentity.users.getStrategy: Prefix with domain, update clients, deprecate old names.
From Dotted → Vendor-Prefixed
Section titled “From Dotted → Vendor-Prefixed”# Beforecommerce.orders.create
# Afteracme.orders/createStrategy:
- Support both formats during transition
- Log usage of deprecated format
- Set deprecation deadline
- Remove old format support
From Any → URN
Section titled “From Any → URN”# Beforeacme.orders/create
# Afterurn:acme:forrst:fn:orders:createStrategy: Usually unnecessary. Only migrate if compliance requires it.
Forrst Recommendations
Section titled “Forrst Recommendations”For Forrst projects, we recommend URN format due to its explicit structure that distinguishes between vendor functions, system extensions, and extension functions.
Recommended Format: URN
Section titled “Recommended Format: URN”URNs provide semantic structure that carries meaning beyond just identification:
urn:{vendor}:{service}:{type}:{function}URN Structures
Section titled “URN Structures”1. Vendor Functions
Section titled “1. Vendor Functions”User-defined functions provided by a vendor/service:
Format: urn:{vendor}:{service}:fn:{function}Examples:
urn:acme:logistics:fn:create-shipmenturn:acme:logistics:fn:list-eventsurn:acme:postal:fn:validate-addressurn:acme:locations:fn:search-locationsurn:stripe:payments:fn:create-chargeurn:acme:orders:fn:cancel-order2. Extension Functions
Section titled “2. Extension Functions”Functions provided by Forrst protocol extensions:
Format: urn:forrst:ext:{extension}:fn:{function}Examples:
urn:forrst:ext:discovery:fn:describeurn:forrst:ext:discovery:fn:capabilitiesurn:forrst:ext:deprecation:fn:list-deprecatedurn:forrst:ext:diagnostics:fn:health-checkurn:forrst:ext:tracing:fn:get-traceurn:forrst:ext:caching:fn:invalidateurn:forrst:ext:rate-limit:fn:get-limits3. System Functions
Section titled “3. System Functions”Core Forrst protocol functions (not extensions):
Format: urn:forrst:system:fn:{function}Examples:
urn:forrst:system:fn:pingurn:forrst:system:fn:versionurn:forrst:system:fn:shutdownURN Segment Reference
Section titled “URN Segment Reference”| Segment | Purpose | Examples |
|---|---|---|
{vendor} | Who owns/provides this | acme, stripe, forrst |
{service} | Domain/service grouping | orders, payments, inventory, logistics |
{type} | What kind of identifier | fn (function), ext (extension), system |
{extension} | Which extension (for ext type) | discovery, deprecation, tracing |
{function} | The function name | create-shipment, describe |
Why URNs for Forrst
Section titled “Why URNs for Forrst”The explicit structure enables:
// Instantly identify what you're dealing with$urn = 'urn:forrst:ext:deprecation:fn:list-deprecated';
// Parse and route based on structureif (str_starts_with($urn, 'urn:forrst:ext:')) { // System extension - special handling} elseif (str_starts_with($urn, 'urn:forrst:system:')) { // Core system function} else { // Vendor function - route to appropriate handler}Debugging clarity:
[ERROR] urn:acme:logistics:fn:create-shipment failed → User code issue[ERROR] urn:forrst:ext:discovery:fn:describe failed → System extension issuePermission patterns:
allow: urn:acme:* # All acme functionsallow: urn:forrst:ext:* # All extensionsdeny: urn:forrst:system:* # Block system functionsReserved Namespaces
Section titled “Reserved Namespaces”urn:forrst:* → Forrst protocol (extensions & system)urn:cline:* → Cline official servicesAll other vendor namespaces are available for user registration.
Function Naming Rules
Section titled “Function Naming Rules”- Use
kebab-casefor function names:create-order, notcreateOrder - Use singular nouns for resources:
order, notorders - Use verb-noun pattern:
create-order,get-user,process-payment
Versioning
Section titled “Versioning”Versioning is handled at the protocol level, not in URNs. This keeps identifiers stable across versions and allows the protocol to manage version negotiation, deprecation, and compatibility.
Examples at Scale
Section titled “Examples at Scale”For a platform with 400 functions across 20 services:
# Payment processing vendorurn:stripe:charges:fn:createurn:stripe:charges:fn:captureurn:stripe:charges:fn:refundurn:stripe:customers:fn:createurn:stripe:customers:fn:update
# Shipping vendorurn:acme:shipments:fn:createurn:acme:shipments:fn:trackurn:acme:rates:fn:calculate
# Internal servicesurn:acme:orders:fn:createurn:acme:orders:fn:cancelurn:acme:inventory:fn:reserveurn:acme:inventory:fn:release
# Forrst extensionsurn:forrst:ext:discovery:fn:describeurn:forrst:ext:discovery:fn:capabilitiesurn:forrst:ext:deprecation:fn:list-deprecatedurn:forrst:ext:diagnostics:fn:health-check
# Forrst systemurn:forrst:system:fn:pingurn:forrst:system:fn:versionThis provides:
- Clear ownership — vendor segment identifies who to contact
- Type distinction —
fnvsextvssystemimmediately visible - Service grouping — related functions organized together
- Extension clarity — which extension provides what function
- Stable identifiers — versioning handled at protocol level
- Permission patterns — wildcard matching on URN prefixes