Skip to content

Commit 268ddf7

Browse files
authored
Merge pull request #182 from daneshk/main
Add Connector development guidelines to BI docs
2 parents 31378b8 + 15e6e02 commit 268ddf7

File tree

3 files changed

+259
-1
lines changed

3 files changed

+259
-1
lines changed

en/docs/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@
7676
"links": [
7777
{"name": "Enterprise Integration Patterns", "url": "references/enterprise-integrations-patterns/"},
7878
{"name": "System requirements", "url": "references/system-requirements/"},
79-
{"name": "AI Usage and Data Handling Guidelines", "url": "references/ai-usage-and-data-handling-guidelines/"}
79+
{"name": "AI Usage and Data Handling Guidelines", "url": "references/ai-usage-and-data-handling-guidelines/"},
80+
{"name": "Connector Development Guidelines", "url": "references/connector-development-guidelines/"}
8081
]
8182
},
8283
{
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
# Connector development guidelines
2+
3+
This guide outlines the complete lifecycle for developing Ballerina connectors for BI, from initial conception through general availability. Following these guidelines ensures consistent quality and maintainability across all connector implementations.
4+
5+
## Naming conventions
6+
7+
### Package names
8+
9+
Package names should use lowercase letters and be descriptive of the service or API being integrated. The name should clearly indicate the external system the connector interacts with.
10+
11+
**Examples:**
12+
- `ballerinax/salesforce`
13+
- `ballerinax/stripe`
14+
- `ballerinax/mongodb`
15+
16+
### Submodules
17+
18+
Submodules should be named in lowercase letters and should reflect the sub-functionality they contain. Submodules should primarily organize code structure within a single connector package. Avoid defining multiple sub-clients in each submodule.
19+
20+
### Hierarchical packages
21+
22+
Hierarchical package names are recommended when you need to distinguish between multiple connectors for the same vendor or service provider. This approach is particularly useful for SaaS products with independent API versioning.
23+
24+
**When to use hierarchical packages:**
25+
- When dealing with the same vendor but different services (e.g., `ballerinax/azure.cosmosdb` vs `ballerinax/azure.storage`)
26+
- When a SaaS product has multiple independent APIs with separate versioning (e.g., `ballerinax/salesforce.bulk` vs `ballerinax/salesforce.soap`)
27+
28+
**Examples:**
29+
- `ballerinax/azure.cosmosdb`
30+
- `ballerinax/azure.storage`
31+
- `ballerinax/salesforce.bulk`
32+
- `ballerinax/salesforce.commons`
33+
- `ballerinax/openai.chat`
34+
- `ballerinax/googleapis.gmail`
35+
36+
### Best practices
37+
38+
- **Clarity and readability**: Use simple nouns that clearly represent the service. Package names should be clear and descriptive, making it easy for developers to understand the purpose of each package. Names like `azureEventHub` or `azure_event_hub` are not idiomatic in Ballerina.
39+
- **Avoid complex patterns**: Do not use camelCase or snake_case in package names
40+
- **Use recognized abbreviations**: Only use abbreviations that are widely recognized by developers (e.g., `aws`, `gcp`)
41+
- **Maintain consistency**: Ensure naming is consistent throughout the connector for an intuitive developer experience
42+
- **Avoid overly deep hierarchies**: While nesting is useful for organization, avoid creating overly deep hierarchies as they increase complexity
43+
- **Avoid split-module conditions**: A split-module condition occurs when different package versions contain the same module, which causes build failures. Choose hierarchical structures carefully to minimize such situations.
44+
45+
## Repository setup
46+
47+
Connectors are developed in dedicated GitHub repositories following a consistent naming pattern:
48+
49+
**Repository Pattern:** `module-[org-name]-[connector-name]`
50+
51+
**Examples:**
52+
- `module-ballerinax-azure.cosmosdb`
53+
- `module-ballerinax-salesforce`
54+
- `module-ballerinax-stripe`
55+
56+
This structure allows for independent versioning, testing, and release cycles for each connector.
57+
58+
## Project structure
59+
60+
A standard connector library includes the following components:
61+
62+
### Required components
63+
64+
- **Ballerina source code**: Core implementation of the connector
65+
- **Tests**: Unit and integration(if possible) tests to ensure functionality
66+
- **Examples**: Sample code demonstrating connector usage
67+
- **Documentation**: User-facing documentation and API references
68+
69+
### Optional components
70+
71+
- **Native code**: Platform-specific implementations when required
72+
- **Compiler plugins**: Custom compile-time behaviors
73+
- **Compiler plugin tests**: Tests for custom compiler plugins
74+
- **Integration tests**: End-to-end tests (typically in separate packages)
75+
76+
### Build and release tools
77+
78+
- **Build tool**: Gradle
79+
- **CI/CD**: GitHub Actions for automated testing and releases
80+
81+
**Build automation for different connector types:**
82+
83+
- **Modules bundled with ballerina-distribution**: Use intermediate packs that incorporate timestamped versions from the Standard Library. This approach maintains build stability and enables prompt failure detection via GitHub packages.
84+
85+
- **Ballerinax modules published independently**: Should use nightly builds from `ballerina-distribution` instead of timestamped builds. The nightly pack can be obtained from the Daily Build in the ballerina-distribution repository. This reduces resource consumption since timestamped builds aren't necessary for independently published modules.
86+
87+
## Connector design principles
88+
89+
### One-to-one mapping
90+
91+
Maintain a one-to-one mapping with external services whenever possible. The connector should reflect the structure and operations of the external API it wraps.
92+
93+
For REST services, resource functions should correspond to external service resources. Combining multiple external resources into single functions is not recommended as it reduces clarity and makes the connector harder to maintain.
94+
95+
### Design decisions
96+
97+
Any design decisions that differ from the external system require special justification and should be documented in the specification.
98+
99+
### Scope management
100+
101+
It is not expected that one connector can map to multiple different APIs, even within the same system. Avoid combining multiple independent APIs into a single connector package.
102+
103+
**Important guideline**: Systems with multiple independent REST APIs (e.g., separate sales and finance APIs within the same platform) should have separate, independent connectors rather than one package with multiple modules. Each connector should have a clear, well-defined scope aligned with a specific service or API.
104+
105+
## Implementation approaches
106+
107+
### REST API connectors (OAS-based)
108+
109+
For REST API-based services, follow these steps:
110+
111+
1. **Obtain OpenAPI specification (OAS)**: Get the OAS directly from the service provider. **Important**: It is not recommended to obtain OAS specifications from third-party providers as they may be outdated or incomplete.
112+
113+
2. **Validate operations**: The OAS must be validated against actual API operations, as specifications often become outdated. Test all operations against the actual API to ensure correctness before proceeding.
114+
115+
3. **Ensure examples in OAS**: The OAS must include an example request and response for each resource action. These examples are essential for mock server generation and testing.
116+
117+
4. **Add OAS to repository**: Include the specification file in the [wso2/api-specs](https://github.com/wso2/api-specs) repository if not already present. The aligned OAS specification file against the Ballerina conventions should be added to the connector repository. Adding the specification to the repository signifies completion of validation and required modifications.
118+
119+
5. **Generate code**: Generate Ballerina client code with resource functions (preferred) or remote functions using the OAS. If using remote functions instead of resource functions, provide justification for this decision.
120+
121+
6. **Generate mock server**: Use the OAS to generate a mock server for testing purposes.
122+
123+
7. **Add unit tests**: Implement unit tests to cover all connector functionality.
124+
125+
8. **Write documentation**: Provide comprehensive documentation for users on how to use the connector, including getting started guides, examples and API references.
126+
127+
For more information on developing OAS-based connectors, please refer to the [Create Your First Connector with Ballerina](https://ballerina.io/learn/create-your-first-connector-with-ballerina/) guide.
128+
129+
### Handwritten connectors
130+
131+
Handwritten connectors are used when wrapping external SDKs or when the API does not have a suitable specification.
132+
133+
**Characteristics:**
134+
- Wrap external SDKs with Ballerina code
135+
- Typically require minimal implementation
136+
- Operations should be stateless and independent
137+
- Must include a `spec.md` file describing functionality
138+
139+
### Specification requirements
140+
141+
- **OAS-based connectors**: For REST API connectors, the OpenAPI Specification serves as the primary specification. Document all sanitations (modifications and alterations to the OAS) in a dedicated `sanitations.md` file within the repository.
142+
143+
- **Handwritten connectors**: Must include a `spec.md` file that comprehensively describes all functionality and operations provided by the connector.
144+
145+
## Testing strategy
146+
147+
### Test necessity
148+
149+
Tests are essential to guard against language changes and potential regressions. All connectors must include comprehensive tests. The primary reasons for testing include:
150+
151+
- **Validating implementation against contracts**: Ensuring the connector behaves according to specifications (not common)
152+
- **Catching regression issues**: Detecting unintended changes in functionality (not common)
153+
- **Detecting breaking changes from language updates**: Identifying issues when Ballerina language is updated (relatively common)
154+
- **Validating against platforms**: Testing compatibility with GraalVM and different Java versions (not common)
155+
156+
**Note**: Some handwritten connectors may include custom logic. In such scenarios, using tests to cover the custom logic and maintaining 80% coverage is mandatory.
157+
158+
### Test execution
159+
160+
- **Timing**: Run tests during releases or when we add new changes to the connector
161+
- **Coverage**: Maintain at least 80% code coverage for any custom business logic
162+
163+
### Testing environments
164+
165+
Prioritize testing approaches in the following order:
166+
167+
1. **Mocking**: Mock external backends using test frameworks.
168+
2. **Docker Images**: Use containerized versions of services.
169+
3. **SaaS Connections**: Connect to actual SaaS endpoints.
170+
171+
Mocking is preferred as it provides faster, more reliable, and cost-effective testing.
172+
173+
## GraalVM compatibility
174+
175+
### Pure Ballerina connectors
176+
177+
Connectors written entirely in Ballerina are GraalVM-compatible only if all their dependencies are also compatible.
178+
179+
### Mixed dependencies
180+
181+
Connectors with native code or Java dependencies require:
182+
- Explicit GraalVM compatibility verification
183+
- Documentation of compatibility status
184+
- Testing with GraalVM native image builds
185+
186+
## Observability
187+
188+
Once a connector is developed, it is important to verify that it includes appropriate observability features for monitoring and tracing in production environments.
189+
190+
### Metrics
191+
192+
Connectors should implement appropriate metrics that are compatible with monitoring tools like Grafana. This enables users to track connector performance, error rates, and usage patterns in production.
193+
194+
### Tracing
195+
196+
Connectors should work well with distributed tracing tools like Jaeger. Proper tracing support helps users debug issues in complex integration flows and understand the full request lifecycle.
197+
198+
### HTTP-based connectors
199+
200+
HTTP-based connectors (those built on top of `http:Client`) already include built-in observability features through the underlying HTTP client. These connectors automatically support metrics and tracing without additional implementation.
201+
202+
### Other connector types
203+
204+
Connectors that are not HTTP-based (e.g., database connectors, messaging connectors) may need to explicitly add metrics and tracing information. Review the observability requirements and add any missing instrumentation.
205+
206+
## Connector maintenance
207+
208+
### Version management
209+
210+
Connector versions should follow semantic versioning (SemVer) principles:
211+
212+
- **Major Version**: Breaking changes to the API
213+
- **Minor Version**: New features, backward-compatible
214+
- **Patch Version**: Bug fixes and minor improvements
215+
216+
### Tracking endpoint API changes
217+
218+
Connector maintainers must actively track changes to the underlying endpoint APIs:
219+
220+
1. **Monitor API Updates**: Regularly check for new versions or updates to the external API
221+
2. **Subscribe to Notifications**: Subscribe to API provider's changelog or release notifications
222+
3. **Review Breaking Changes**: Assess whether API changes require connector updates
223+
224+
### Release new versions
225+
226+
Release a new connector version whenever:
227+
228+
- **New API Version Available**: The endpoint API releases a new version with new features or operations
229+
- **Breaking Changes**: The external API introduces breaking changes that require connector updates
230+
- **Deprecated Operations**: The API deprecates operations that need to be marked or removed
231+
- **Bug Fixes**: Issues are discovered in the connector implementation
232+
- **Security Updates**: Security vulnerabilities are identified in dependencies or the connector itself
233+
234+
### Version release process
235+
236+
1. **Update dependencies**: Update to the latest stable dependencies
237+
2. **Test thoroughly**: Run full test suite against the new API version
238+
3. **Update documentation**: Reflect any API changes in connector documentation
239+
4. **Update changelog**: Document all changes in the changelog
240+
5. **Tag release**: Create a git tag following the versioning scheme
241+
6. **Publish**: Publish to Ballerina Central
242+
243+
### Backward compatibility
244+
245+
When possible, maintain backward compatibility:
246+
247+
- Deprecate rather than immediately remove features
248+
- Provide migration guides for breaking changes
249+
250+
### Deprecation policy
251+
252+
When deprecating connector features:
253+
254+
1. Mark the feature as deprecated in the code and documentation
255+
2. Suggest alternative approaches in deprecation messages
256+
3. Update examples and documentations to use recommended patterns

en/mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ nav:
174174
- "Enterprise Integrations Patterns": references/enterprise-integrations-patterns.md
175175
- "System Requirements": references/system-requirements.md
176176
- "AI Usage & Data Handling Guidelines": references/ai-usage-and-data-handling-guidelines.md
177+
- "Connector Development Guidelines": references/connector-development-guidelines.md
177178

178179
- Release Notes:
179180
- Release Note: wso2-integrator-bi-release-notes.md

0 commit comments

Comments
 (0)