diff --git a/en/docs/develop/integration-artifacts/event/kafka.md b/en/docs/develop/integration-artifacts/event/kafka.md index b4d83e1b..86d28744 100644 --- a/en/docs/develop/integration-artifacts/event/kafka.md +++ b/en/docs/develop/integration-artifacts/event/kafka.md @@ -3,10 +3,54 @@ title: Kafka description: Consume messages from Apache Kafka topics with consumer group management and offset control. --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # Kafka Consume messages from Apache Kafka topics with consumer group management, offset control, and schema-aware deserialization. +## Creating a Kafka consumer + + + + +1. Click the **+** **Add Artifacts** button in the canvas or click **+** next to **Entry Points** in the sidebar. +2. In the **Artifacts** panel, select **Kafka** under **Event Integration**. + + ![Artifacts panel showing Kafka under Event Integration](/img/develop/integration-artifacts/event/kafka/step-2.png) + +3. In the creation form, fill in the following fields: + + ![Kafka consumer creation form](/img/develop/integration-artifacts/event/kafka/step-creation-form.png) + + **Service Configurations** + + + | Field | Description | + |---|---| + | **Bootstrap Servers** | Comma-separated list of Kafka broker addresses (e.g., `localhost:9092`). Required. | + | **Topic(s)** | One or more Kafka topic names to subscribe to. Required. | + + **Advanced Configurations** + + Expand **Advanced Configurations** to set additional options including the consumer group ID, offset reset policy, and polling interval. + +4. Click **Create**. + +5. WSO2 Integrator opens the **Kafka Consumer Designer**. The header shows the listener configuration pill and the list of event handlers. + + ![Kafka Consumer Designer showing the listener configuration](/img/develop/integration-artifacts/event/kafka/step-3.png) + +6. Click the `onConsumerRecord` handler row to open it in the **flow designer**. + + ![Flow designer showing the onConsumerRecord handler canvas](/img/develop/integration-artifacts/event/kafka/step-4.png) + +7. Use the flow canvas to add integration steps — database writes, HTTP calls, and transformations. + + + + ```ballerina import ballerinax/kafka; @@ -45,6 +89,9 @@ service on orderListener { } ``` + + + ## Offset Management Strategies | Strategy | Configuration | Behavior | @@ -54,7 +101,7 @@ service on orderListener { | **Seek to beginning** | `autoOffsetReset: "earliest"` | Reprocess from the beginning of the topic | | **Seek to end** | `autoOffsetReset: "latest"` | Skip to the latest messages only | -## Common Patterns + ### Acknowledgment Strategies diff --git a/en/docs/develop/integration-artifacts/service/graphql-service.md b/en/docs/develop/integration-artifacts/service/graphql-service.md index 92f2c618..dbf3a1c9 100644 --- a/en/docs/develop/integration-artifacts/service/graphql-service.md +++ b/en/docs/develop/integration-artifacts/service/graphql-service.md @@ -3,9 +3,46 @@ title: GraphQL Service description: Build GraphQL APIs with queries, mutations, and subscriptions. (Beta) --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # GraphQL Service -Build GraphQL APIs with queries, mutations, and subscriptions. +GraphQL services let you build flexible APIs where clients request exactly the data they need. WSO2 Integrator automatically generates the GraphQL schema from your Ballerina types and supports queries, mutations, and real-time subscriptions. + +:::note Beta +GraphQL service support is currently in beta. +::: + +## Creating a GraphQL service + + + + +1. Open the **WSO2 Integrator** sidebar in VS Code. +2. Click **+** next to **Services**. +3. Select **GraphQL Service** from the artifact type list. +4. In the creation form, fill in: + - **Name** — a name for the service. + - **Port** — the listener port (default: `9090`). + - **Base Path** — the GraphQL endpoint path (e.g., `/graphql`). +5. Click **Create**. + + + +6. WSO2 Integrator opens the service in the **flow designer**. The canvas displays separate nodes for queries, mutations, and subscriptions. +7. Click **+ Add Query** to add a query resource, **+ Add Mutation** for mutations, or **+ Add Subscription** for subscriptions. +8. For each operation, define the return type and any input arguments. +9. Use the action palette to add data-fetching logic inside each operation. + + + +10. WSO2 Integrator generates the schema automatically from the Ballerina type definitions. Click **View Schema** to preview the generated SDL. + + + + + ```ballerina import ballerina/graphql; @@ -34,4 +71,59 @@ service /graphql on new graphql:Listener(9090) { } ``` -GraphQL services automatically generate the schema from Ballerina types. Use the built-in GraphQL Playground for interactive testing. + + + +## GraphQL operation types + +| Operation | Keyword | Description | +|---|---|---| +| **Query** | `resource function get` | Read data — analogous to HTTP GET | +| **Mutation** | `remote function` | Write data — analogous to HTTP POST/PUT/DELETE | +| **Subscription** | `resource function subscribe` | Real-time updates via WebSocket | + +## Schema generation + +Ballerina generates the GraphQL schema from your record types and function signatures automatically. No separate SDL file is needed. + +```ballerina +type Product record {| + string id; + string name; + decimal price; + string category; +|}; + +type ProductInput record {| + string name; + decimal price; + string category; +|}; +``` + +The above types map to the following GraphQL schema: + +```graphql +type Product { + id: String! + name: String! + price: Decimal! + category: String! +} + +input ProductInput { + name: String! + price: Decimal! + category: String! +} +``` + +## GraphQL Playground + +Use the built-in GraphQL Playground for interactive testing. Navigate to `http://localhost:9090/graphql` in your browser after starting the service. + +## What's next + +- [HTTP Service](http-service.md) — expose integration logic over REST +- [Types](../supporting/types.md) — define shared record types for schema generation +- [Connections](../supporting/connections.md) — configure data source connections diff --git a/en/docs/develop/integration-artifacts/service/grpc-service.md b/en/docs/develop/integration-artifacts/service/grpc-service.md index 5175f819..7a2fd5a7 100644 --- a/en/docs/develop/integration-artifacts/service/grpc-service.md +++ b/en/docs/develop/integration-artifacts/service/grpc-service.md @@ -3,9 +3,42 @@ title: gRPC Service description: Define services using Protocol Buffers and generate Ballerina code for gRPC. --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # gRPC Service -Define services using Protocol Buffers and generate Ballerina code. +gRPC services use Protocol Buffers (protobuf) to define strongly-typed contracts and support four communication patterns: unary, server streaming, client streaming, and bidirectional streaming. WSO2 Integrator generates Ballerina service stubs from your `.proto` files. + +## Creating a gRPC service + + + + +1. Open the **WSO2 Integrator** sidebar in VS Code. +2. Click **+** next to **Services**. +3. Select **gRPC Service** from the artifact type list. +4. In the creation form, fill in: + - **Name** — a name for the service. + - **Port** — the gRPC listener port (default: `9090`). + - **Proto File** — optionally upload an existing `.proto` file, or start with a blank service. +5. Click **Create**. + + + +6. WSO2 Integrator opens the service in the **flow designer**. Each RPC method from the proto definition appears as a separate resource node. +7. Click a resource node to open its implementation canvas. +8. Add integration steps using the action palette — database lookups, HTTP calls, and transformations. +9. To add a new RPC method, click **+ Add RPC** in the service node and choose the communication pattern (unary, server streaming, client streaming, or bidirectional). + + + +10. Switch to **Code View** to inspect the generated Ballerina service stub and edit the descriptor annotation if needed. + + + + + ```ballerina import ballerina/grpc; @@ -35,3 +68,34 @@ service "OrderService" on new grpc:Listener(9090) { } } ``` + + + + +## RPC communication patterns + +| Pattern | Description | Use case | +|---|---|---| +| **Unary** | Single request, single response | Standard CRUD operations | +| **Server streaming** | Single request, stream of responses | Large result sets, real-time feeds | +| **Client streaming** | Stream of requests, single response | Bulk uploads, batch inserts | +| **Bidirectional streaming** | Stream of requests and responses | Chat, real-time collaboration | + +## Generating code from proto files + +WSO2 Integrator uses `bal grpc` to generate service stubs from protobuf definitions. + +```bash +# Generate Ballerina service stub from a .proto file +bal grpc --input order_service.proto --output gen/ --mode service +``` + +This generates: +- `OrderService.bal` — service interface with all RPC methods +- `order_service_pb.bal` — message types and the descriptor constant + +## What's next + +- [HTTP Service](http-service.md) — expose integration logic over REST +- [Connections](../supporting/connections.md) — configure gRPC client connections +- [Types](../supporting/types.md) — define shared message types diff --git a/en/docs/develop/integration-artifacts/service/http-service.md b/en/docs/develop/integration-artifacts/service/http-service.md index bace4355..c0419287 100644 --- a/en/docs/develop/integration-artifacts/service/http-service.md +++ b/en/docs/develop/integration-artifacts/service/http-service.md @@ -3,125 +3,99 @@ title: HTTP Service description: Build REST APIs, webhooks, and data services with HTTP. --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # HTTP Service -HTTP services are the foundation for REST APIs, webhooks, and data services. +HTTP services are the foundation for REST APIs, webhooks, and data services in WSO2 Integrator. Use them to expose integration logic over HTTP with full support for path and query parameters, typed request/response payloads, CORS, interceptors, and TLS. -## Creating an HTTP Service +## Creating an HTTP service -```ballerina -import ballerina/http; + + -configurable int port = 8090; +1. Click the **+** **Add Artifacts** button in the canvas or click **+** next to **Entry Points** in the sidebar. +2. In the **Artifacts** panel, select **HTTP Service** under **Integration as API**. -service /api on new http:Listener(port) { + ![Artifacts panel showing HTTP Service under Integration as API](/img/develop/integration-artifacts/service/http-service/step-2.png) - resource function get greeting() returns string { - return "Hello from WSO2 Integrator!"; - } -} -``` +3. In the creation form, fill in the following fields: -## Defining Resources and Methods + ![HTTP Service creation form](/img/develop/integration-artifacts/service/http-service/step-creation-form.png) -Each resource function maps to an HTTP method and path. Ballerina's type system ensures request and response payloads are validated automatically. + **Service Contract** -```ballerina -service /orders on new http:Listener(8090) { + | Option | Description | + |---|---| + | **Design From Scratch** | Creates a new service with empty resources. Default selection. | + | **Import From OpenAPI Specification** | Generates service stubs from an existing OpenAPI (Swagger) file or URL. | - // GET /orders - resource function get .() returns Order[]|error { - return getOrders(); - } + **Service Base Path** - // GET /orders/{id} - resource function get [string id]() returns Order|http:NotFound { - Order? order = getOrder(id); - return order ?: http:NOT_FOUND; - } + | Field | Description | + |---|---| + | **Service Base Path** | URL base path for the service (e.g., `/api`). Must not end with `/` unless it is the bare root path `/`. | - // POST /orders - resource function post .(Order order) returns Order|http:BadRequest|error { - return createOrder(order); - } + **Advanced Configurations** - // PUT /orders/{id} - resource function put [string id](Order order) returns Order|http:NotFound|error { - return updateOrder(id, order); - } + Expand **Advanced Configurations** to choose the HTTP listener: - // DELETE /orders/{id} - resource function delete [string id]() returns http:NoContent|http:NotFound { - boolean deleted = deleteOrder(id); - return deleted ? http:NO_CONTENT : http:NOT_FOUND; - } -} -``` + | Option | Description | + |---|---| + | **Shared Listener (Port 9090)** | Attaches the service to the project's shared HTTP listener on port 9090. Use this when multiple services share one listener. | + | **Custom Listener** | Creates a dedicated listener. Enter the port number in the **Listener Port** field that appears. | + +4. Click **Create**. + +5. WSO2 Integrator opens the service in the **Service Designer**. The header shows the attached listener pill, the base path, and the list of resource functions. -## Path Parameters and Query Parameters + ![Service Designer showing the HTTP service canvas](/img/develop/integration-artifacts/service/http-service/step-3.png) + +6. Click **+ Resource** to add a new HTTP resource, then select its HTTP method and path. +7. Click the resource row to open it in the **flow designer**. + + ![Flow designer showing the resource canvas](/img/develop/integration-artifacts/service/http-service/step-4.png) + +8. Use the flow canvas to add integration steps — HTTP calls, database queries, and transformations. + + + ```ballerina -service /api on new http:Listener(8090) { +import ballerina/http; - // Path parameter: /api/users/42 - resource function get users/[int userId]() returns User|error { - return getUser(userId); - } +configurable int port = 8090; - // Query parameters: /api/products?category=electronics&limit=10 - resource function get products(string? category, int limit = 20) returns Product[]|error { - return searchProducts(category, limit); - } +service /api on new http:Listener(port) { - // Multiple path segments: /api/orgs/wso2/repos/integrator - resource function get orgs/[string org]/repos/[string repo]() returns Repository|error { - return getRepository(org, repo); + resource function get greeting() returns string { + return "Hello from WSO2 Integrator!"; } } ``` -## Request and Response Payload Types + + -Define typed records for request and response payloads. Ballerina automatically validates and deserializes incoming JSON. +## Service configuration -```ballerina -type OrderRequest record {| - string customerId; - LineItem[] items; - string? shippingAddress; -|}; +Service configuration controls the base path and advanced service-level settings such as CORS policy, authentication, and payload validation. -type OrderResponse record {| - string orderId; - string status; - decimal totalAmount; - string createdAt; -|}; + + -resource function post orders(OrderRequest request) returns OrderResponse|http:BadRequest|error { - // request is already validated and deserialized - OrderResponse response = check processOrder(request); - return response; -} -``` +In the **Service Designer**, click **Configure** in the service header to open the **HTTP Service Configuration** panel. -## Headers and Content Types +| Field | Description | +|---|---| +| **Base Path** | URL base path for the service (e.g., `/api`). Required. | +| **Service Configuration** | Advanced service-level settings (CORS, auth, compression, etc.). Enter a `@http:ServiceConfig` record expression. | -```ballerina -resource function post webhook( - @http:Header string x\-api\-key, - @http:Header {name: "Content-Type"} string contentType, - http:Request req -) returns http:Accepted|http:Unauthorized { - if x\-api\-key != expectedKey { - return http:UNAUTHORIZED; - } - // Process the webhook payload - return http:ACCEPTED; -} -``` + + -## CORS Configuration +Service-level settings map to the `@http:ServiceConfig` annotation placed before the `service` declaration: ```ballerina @http:ServiceConfig { @@ -133,13 +107,35 @@ resource function post webhook( } } service /api on new http:Listener(8090) { - // Resources inherit CORS configuration + // Resources inherit CORS configuration. } ``` -## Interceptors and Middleware +All `@http:ServiceConfig` fields: + +| Field | Type | Default | Description | +|---|---|---|---| +| `host` | `string` | `"b7a.default"` | Virtual host name | +| `compression` | `CompressionConfig` | `{}` | Response compression settings | +| `chunking` | `Chunking` | `CHUNKING_AUTO` | Chunked transfer encoding mode | +| `cors` | `CorsConfig` | `{}` | CORS policy for all resources | +| `auth` | `ListenerAuthConfig[]` | — | Service-level authentication | +| `mediaTypeSubtypePrefix` | `string` | — | Custom media type subtype prefix | +| `treatNilableAsOptional` | `boolean` | `true` | Treat nilable parameters as optional | +| `validation` | `boolean` | `true` | Enable inbound payload validation | -Use request/response interceptors for cross-cutting concerns such as logging, authentication, and rate limiting. +**CORS configuration** (`CorsConfig`): + +| Field | Type | Default | Description | +|---|---|---|---| +| `allowOrigins` | `string[]` | `[]` | Permitted origins | +| `allowMethods` | `string[]` | `[]` | Permitted HTTP methods | +| `allowHeaders` | `string[]` | `[]` | Permitted request headers | +| `exposeHeaders` | `string[]` | `[]` | Response headers accessible to the browser | +| `allowCredentials` | `boolean` | `false` | Allow cookies and credentials | +| `maxAge` | `decimal` | `-1` | Preflight cache duration in seconds | + +**Interceptors:** ```ballerina service class LoggingInterceptor { @@ -154,69 +150,285 @@ service class LoggingInterceptor { } } -service class AuthInterceptor { - *http:RequestInterceptor; +@http:ServiceConfig { + interceptors: [new LoggingInterceptor()] +} +service /api on new http:Listener(8090) { + resource function get data() returns json { + return {message: "protected"}; + } +} +``` - resource function 'default [string... path]( - http:RequestContext ctx, - @http:Header string authorization - ) returns http:NextService|http:Unauthorized|error? { - if !check validateToken(authorization) { - return http:UNAUTHORIZED; - } - return ctx.next(); + + + +## Listener configuration + +The listener binds to a port and handles incoming HTTP connections. When you create an HTTP service, WSO2 Integrator automatically creates an inline listener. You can also declare a named listener and attach multiple services to it. + + + + +In the **HTTP Service Configuration** panel, select **Http Listener** under **Attached Listeners** to configure the listener. + +| Field | Description | Default | +|---|---|---| +| **Port** | Listening port of the HTTP service listener. Required. | `8090` | +| **Host** | Host name or IP address the listener binds to. | `0.0.0.0` | +| **HTTP1 Settings** | HTTP/1.x protocol settings (keep-alive, max pipelined requests). | `{}` | +| **Secure Socket** | TLS/SSL configuration. Configure this to enable HTTPS. | `()` | +| **HTTP Version** | Highest HTTP version the endpoint supports. | HTTP/2.0 | +| **Timeout** | Read/write timeout in seconds. Set to `0` to disable. | `60` | +| **Server** | Value for the `Server` response header. | `()` | +| **Request Limits** | Inbound size limits for URI, headers, and request body. | `{}` | +| **Graceful Stop Timeout** | Grace period in seconds before the listener force-stops. | `0` | +| **Socket Config** | Server socket settings (e.g., `soBackLog` queue length). | `{}` | +| **HTTP2 Initial Window Size** | Initial HTTP/2 flow-control window size in bytes. | `65535` | +| **Min Idle Time In Stale State** | Minimum seconds to hold an HTTP/2 connection open after `GOAWAY`. Set to `-1` to close after all in-flight streams finish. | `300` | +| **Time Between Stale Eviction** | Interval in seconds between HTTP/2 stale connection eviction runs. | `30` | + +Click **+ Attach Listener** at the bottom of the panel to attach an additional listener or to select an existing named listener. + + + + +**Inline listener** (created together with the service): + +```ballerina +configurable int port = 8090; + +service /api on new http:Listener(port) { + resource function get greeting() returns string { + return "Hello!"; } } +``` -listener http:Listener ep = new (8090); +**Using a named listener** — declare the listener at module level and attach multiple services to it. This corresponds to the "select existing listener" option in the creation form. -// Apply interceptors to the service -@http:ServiceConfig { - interceptors: [new LoggingInterceptor(), new AuthInterceptor()] +```ballerina +listener http:Listener httpListener = new (8090, { + host: "0.0.0.0", + httpVersion: http:HTTP_2_0, + timeout: 60, + secureSocket: { + key: { + certFile: "/path/to/cert.pem", + keyFile: "/path/to/key.pem" + } + } +}); + +service /api on httpListener { + resource function get greeting() returns string { + return "Hello!"; + } } -service /api on ep { - resource function get secured\-data() returns json { - return {message: "This is protected data"}; + +service /health on httpListener { + resource function get .() returns json { + return {status: "ok"}; } } ``` -## Error Responses and Status Codes +All `http:ListenerConfiguration` fields: + +| Field | Type | Default | Description | +|---|---|---|---| +| `host` | `string` | `"0.0.0.0"` | Bind address | +| `http1Settings` | `ListenerHttp1Settings` | `{}` | HTTP/1.x keep-alive and pipelining | +| `secureSocket` | `ListenerSecureSocket?` | `()` | TLS/SSL configuration | +| `httpVersion` | `HttpVersion` | `HTTP_2_0` | Highest supported HTTP version | +| `timeout` | `decimal` | `60` | Read/write timeout in seconds | +| `server` | `string?` | `()` | `Server` response header value | +| `requestLimits` | `RequestLimitConfigs` | `{}` | URI, header, and body size limits | +| `gracefulStopTimeout` | `decimal` | `0` | Grace period for `gracefulStop` in seconds | +| `socketConfig` | `ServerSocketConfig` | `{}` | Server socket settings | +| `http2InitialWindowSize` | `int` | `65535` | HTTP/2 initial flow-control window size | +| `minIdleTimeInStaleState` | `decimal` | `300` | Min seconds to keep a `GOAWAY` connection open | +| `timeBetweenStaleEviction` | `decimal` | `30` | HTTP/2 stale connection eviction interval | + + + + +## Resource configuration + +Resources define the individual HTTP endpoints exposed by a service. Each resource maps to an HTTP method and a path. + + + + +In the **Service Designer**, click the settings icon (⚙) on a resource row to open the **Resource Configuration** panel. You see the same panel when you click **+ Resource** to add a new resource. + +**Method and path:** + +| Field | Description | +|---|---| +| **HTTP Method** | HTTP verb. Options: `GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`, `OPTIONS`. | +| **Resource Path** | Path segment appended to the service base path. Use `{paramName}` notation to define path parameters inline. | +| **+ Path Param** | Add a typed path parameter. Appears as `[type name]` in the resource function signature. | +| **+ Query Parameter** | Add a typed query parameter. Appears as a named parameter in the function signature. | +| **+ Header** | Add a named header parameter annotated with `@http:Header`. | + +**Advanced Parameters** (expand to reveal): + +| Parameter | Description | +|---|---| +| **Request** | Inject the full `http:Request` object, giving access to the request body, all headers, and metadata. | +| **Headers** | Inject `http:Headers` to access all HTTP headers sent by the client. | +| **Caller** | Inject `http:Caller` for fine-grained response control and caller identity information. | + +**Responses:** + +Add one or more response definitions. Each entry specifies an HTTP status code and a return type (e.g., `200` → `string`). Use **+ Response** to add additional status codes. + +**Advanced Configurations** (expand to reveal): resource-level `@http:ResourceConfig` settings including per-resource CORS overrides, authentication, linked resources, and accepted/produced media types. + + + + +**Resource function signature:** ```ballerina -type ErrorResponse record {| - string code; - string message; - string[] details?; -|}; +resource function /<[type param]>( + ParamType paramName, // query parameter (named) + @http:Payload PayloadType p, // request body + @http:Header string headerName, // named header + http:Request req, // full request object + http:Caller caller // caller object +) returns ResponseType { +} +``` -resource function get orders/[string id]() returns Order|http:NotFound|http:InternalServerError { - Order|error result = getOrder(id); - if result is error { - ErrorResponse errBody = {code: "NOT_FOUND", message: "Order not found"}; - http:NotFound notFound = {body: errBody}; - return notFound; +**Path parameters:** + +```ballerina +// GET /api/users/42 +resource function get users/[int userId]() returns User|error { + return getUser(userId); +} + +// GET /api/files/docs/report.pdf (rest parameter) +resource function get files/[string... path]() returns File|error { + return getFile(path); +} +``` + +**Query parameters:** + +```ballerina +// GET /api/products?category=electronics&limit=10 +resource function get products(string? category, int limit = 20) returns Product[]|error { + return searchProducts(category, limit); +} +``` + +**Request body:** + +```ballerina +resource function post orders(@http:Payload Order order) returns Order|http:BadRequest|error { + return createOrder(order); +} +``` + +**Named headers:** + +```ballerina +resource function get data(@http:Header string authorization) returns json|http:Unauthorized { + // Use the Authorization header value. +} +``` + +**CRUD pattern:** + +```ballerina +service /orders on new http:Listener(8090) { + + resource function get .() returns Order[]|error { + return getOrders(); + } + + resource function get [string id]() returns Order|http:NotFound { + Order? order = getOrder(id); + return order ?: http:NOT_FOUND; + } + + resource function post .(Order order) returns Order|http:BadRequest|error { + return createOrder(order); + } + + resource function put [string id](Order order) returns Order|http:NotFound|error { + return updateOrder(id, order); + } + + resource function delete [string id]() returns http:NoContent|http:NotFound { + boolean deleted = deleteOrder(id); + return deleted ? http:NO_CONTENT : http:NOT_FOUND; } - return result; } ``` -## Service Configuration Options +**HTTP status code return types:** -| Configuration | Description | +| Return type | HTTP status | |---|---| -| `port` | Listener port number | -| `host` | Bind address (default: `0.0.0.0`) | -| `secureSocket` | TLS/SSL configuration | -| `timeout` | Request/connection timeout | -| `maxHeaderSize` | Maximum HTTP header size | -| `maxPayloadSize` | Maximum request body size | +| `string`, `json`, `record`, `byte[]` | 200 OK | +| `http:Created` | 201 Created | +| `http:Accepted` | 202 Accepted | +| `http:NoContent` | 204 No Content | +| `http:BadRequest` | 400 Bad Request | +| `http:Unauthorized` | 401 Unauthorized | +| `http:Forbidden` | 403 Forbidden | +| `http:NotFound` | 404 Not Found | +| `http:InternalServerError` | 500 Internal Server Error | +| `error` | 500 Internal Server Error | + + + + + + +## What's next + +- [gRPC Service](grpc-service.md) — define services using Protocol Buffers +- [Connections](../supporting/connections.md) — configure HTTP client connections to call external services +- [Data Mapper](../supporting/data-mapper.md) — transform request/response payloads between formats diff --git a/en/docs/develop/integration-artifacts/service/tcp-service.md b/en/docs/develop/integration-artifacts/service/tcp-service.md index c0c3e814..9593c30f 100644 --- a/en/docs/develop/integration-artifacts/service/tcp-service.md +++ b/en/docs/develop/integration-artifacts/service/tcp-service.md @@ -3,9 +3,46 @@ title: TCP Service description: Handle raw TCP connections for custom protocol implementations. (Beta) --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # TCP Service -Handle raw TCP connections for custom protocol implementations. +TCP services handle raw TCP connections and are suitable for custom binary or text-based protocol implementations where HTTP overhead is not acceptable. WSO2 Integrator generates a connection service class with lifecycle callbacks for connection open, data receipt, and close events. + +:::note Beta +TCP service support is currently in beta. +::: + +## Creating a TCP service + + + + +1. Open the **WSO2 Integrator** sidebar in VS Code. +2. Click **+** next to **Services**. +3. Select **TCP Service** from the artifact type list. +4. In the creation form, fill in: + - **Name** — a name for the service. + - **Port** — the TCP listener port (default: `3000`). +5. Click **Create**. + + + +6. WSO2 Integrator generates a TCP listener service and a connection service class. The flow designer shows two nodes: + - **onConnect** — called when a new client connects; returns the connection service instance. + - Connection service handlers: **onBytes**, **onClose**, and **onError**. +7. Click the **onBytes** node to implement the data processing logic. +8. Use `caller->writeBytes()` to send a response back to the client. + + + +9. Click **onClose** to add cleanup logic when a connection closes. + + + + + ```ballerina import ballerina/tcp; @@ -33,3 +70,50 @@ service class TcpHandler { } } ``` + + + + +## Connection lifecycle callbacks + +| Callback | Trigger | Typical use | +|---|---|---| +| `onConnect` | New TCP client connects | Initialize per-connection state, return `ConnectionService` | +| `onBytes` | Data received from client | Parse and process the payload, write response | +| `onClose` | Client disconnects | Release per-connection resources | +| `onError` | Connection error | Log and handle error conditions | + +## Common patterns + +### Frame-delimited protocol + +```ballerina +service class FrameHandler { + *tcp:ConnectionService; + private byte[] buffer = []; + + remote function onBytes(tcp:Caller caller, readonly & byte[] data) returns error? { + // Accumulate bytes until a complete frame is received + self.buffer.push(...data); + if self.buffer.length() >= 4 { + // First 4 bytes encode frame length + int frameLen = readInt32(self.buffer.slice(0, 4)); + if self.buffer.length() >= 4 + frameLen { + byte[] frame = self.buffer.slice(4, 4 + frameLen); + self.buffer = self.buffer.slice(4 + frameLen); + check processFrame(caller, frame); + } + } + } + + remote function onClose() { + log:printInfo("Connection closed, pending bytes discarded", + pending = self.buffer.length()); + } +} +``` + +## What's next + +- [WebSocket Service](websocket-service.md) — real-time bidirectional communication with a higher-level protocol +- [HTTP Service](http-service.md) — expose integration logic over REST diff --git a/en/docs/develop/integration-artifacts/service/websocket-service.md b/en/docs/develop/integration-artifacts/service/websocket-service.md index 764532e0..d3da5e10 100644 --- a/en/docs/develop/integration-artifacts/service/websocket-service.md +++ b/en/docs/develop/integration-artifacts/service/websocket-service.md @@ -3,9 +3,46 @@ title: WebSocket Service description: Handle real-time bidirectional communication with WebSocket. --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + # WebSocket Service -Handle real-time bidirectional communication with WebSocket. +WebSocket services enable persistent, full-duplex communication between clients and the server. Use them for real-time features such as live dashboards, chat applications, collaborative tools, and push notifications. + +## Creating a WebSocket service + + + + +1. Open the **WSO2 Integrator** sidebar in VS Code. +2. Click **+** next to **Services**. +3. Select **WebSocket Service** from the artifact type list. +4. In the creation form, fill in: + - **Name** — a name for the service. + - **Port** — the WebSocket listener port (default: `8080`). + - **Base Path** — the WebSocket endpoint path (e.g., `/ws`). +5. Click **Create**. + + + +6. WSO2 Integrator generates an upgrade resource and a WebSocket service class. The flow designer shows the following handler nodes: + - **onOpen** — called when a client successfully upgrades the connection. + - **onTextMessage** — called when the client sends a text frame. + - **onBinaryMessage** — called when the client sends a binary frame. + - **onClose** — called when the connection closes. +7. Click **onOpen** to add connection initialization logic (for example, broadcasting a welcome message). +8. Click **onTextMessage** to implement the message handling logic. + + + +9. Use `caller->writeTextMessage()` or `caller->writeBinaryMessage()` to push messages to the client. +10. To broadcast to all connected clients, maintain a shared collection of callers and iterate over them in the handler. + + + + + ```ballerina import ballerina/websocket; @@ -34,3 +71,55 @@ service class ChatService { } } ``` + + + + +## WebSocket lifecycle callbacks + +| Callback | Trigger | Typical use | +|---|---|---| +| `onOpen` | Connection upgrade successful | Initialize session state, send welcome message | +| `onTextMessage` | Text frame received | Parse and route message, broadcast to others | +| `onBinaryMessage` | Binary frame received | Handle binary payloads (files, media) | +| `onClose` | Connection closed | Remove client from broadcast list, release resources | +| `onError` | Connection error | Log and handle errors | + +## Common patterns + +### Broadcast to all connected clients + +```ballerina +// Shared connection registry +isolated map connections = {}; + +service class BroadcastService { + *websocket:Service; + + remote function onOpen(websocket:Caller caller) returns error? { + lock { + connections[caller.getConnectionId()] = caller; + } + } + + remote function onTextMessage(websocket:Caller caller, string message) returns error? { + // Broadcast to all connected clients + lock { + foreach websocket:Caller conn in connections { + check conn->writeTextMessage(message); + } + } + } + + remote function onClose(websocket:Caller caller, int statusCode, string reason) { + lock { + _ = connections.remove(caller.getConnectionId()); + } + } +} +``` + +## What's next + +- [HTTP Service](http-service.md) — expose integration logic over REST +- [TCP Service](tcp-service.md) — raw TCP for custom binary protocols diff --git a/en/docs/get-started/quick-start-ai-agent.md b/en/docs/get-started/quick-start-ai-agent.md index fc09fdc7..3b66ef90 100644 --- a/en/docs/get-started/quick-start-ai-agent.md +++ b/en/docs/get-started/quick-start-ai-agent.md @@ -4,46 +4,49 @@ title: "Quick Start: Build an AI Agent" description: Create an intelligent AI agent powered by LLMs with tool calling. --- -# Quick Start: Build an AI Agent +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Quick start: Build an AI agent **Time:** Under 15 minutes | **What you'll build:** An AI agent that connects to an LLM, uses tools, and responds to queries through a GraphQL endpoint. ## Prerequisites -- [WSO2 Integrator extension installed](install.md) +- [WSO2 Integrator installed](install.md) - An OpenAI API key ## Architecture -``` -Client GraphQL Service LLM (OpenAI) - │ localhost:8080 │ - │ mutation Task(query) │ │ - │────────────────────────────►│ prompt + tools │ - │ │────────────────────────►│ - │ │◄────────────────────────│ - │◄────────────────────────────│ response │ - │ { data: { task: "..." } } │ │ -``` + -## Step 1: Create the Project +## Step 1: Create the project -1. Open the WSO2 Integrator sidebar in VS Code. -2. Click **Create New Integration**. -3. Enter the integration name (e.g., `AIAgent`). +1. Open WSO2 Integrator. +2. Select **Create New Integration**. +3. Enter the integration name (for example, `AIAgent`). -## Step 2: Add a GraphQL Service +## Step 2: Add a GraphQL service 1. Add a **GraphQL Service** artifact. 2. Add a mutation named `task` that accepts a `query: string` parameter. -## Step 3: Configure the Inline Agent +## Step 3: Configure the inline agent 1. Inside the mutation, implement an **Inline Agent**. 2. Configure the model provider (WSO2 default or OpenAI). 3. Set up agent memory and tools. -In code: + + ```ballerina import ballerina/graphql; @@ -70,7 +73,21 @@ service /graphql on new graphql:Listener(8080) { } ``` -## Step 4: Configure the API Key + + + + + + + + +## Step 4: Configure the API key Create a `Config.toml` file: @@ -78,9 +95,9 @@ Create a `Config.toml` file: openaiKey = "" ``` -## Step 5: Run and Test +## Step 5: Run and test -1. Click **Run** in the toolbar. +1. Select **Run** in the toolbar. 2. Test with curl: ```bash @@ -89,9 +106,9 @@ curl -X POST http://localhost:8080/graphql \ -d '{"query": "mutation Task { task(query: \"What is WSO2 Integrator?\") }"}' ``` -## What's Next +## What's next -- [GenAI Overview](/docs/genai) -- Full guide to AI capabilities -- [Chat Agents](/docs/genai/agents/chat-agents) -- Build interactive chat agents -- [MCP Servers](/docs/genai/mcp/exposing-mcp-servers) -- Expose tools to AI assistants -- [RAG Applications](/docs/genai/rag/architecture-overview) -- Add knowledge bases to agents +- [GenAI overview](/docs/genai) -- Full guide to AI capabilities +- [Chat agents](/docs/genai/agents/chat-agents) -- Build interactive chat agents +- [MCP servers](/docs/genai/mcp/exposing-mcp-servers) -- Expose tools to AI assistants +- [RAG applications](/docs/genai/rag/architecture-overview) -- Add knowledge bases to agents diff --git a/en/docs/get-started/quick-start-api.md b/en/docs/get-started/quick-start-api.md index 2daae75d..f3629342 100644 --- a/en/docs/get-started/quick-start-api.md +++ b/en/docs/get-started/quick-start-api.md @@ -4,46 +4,49 @@ title: "Quick Start: Integration as API" description: Build an HTTP service that calls an external API and returns a greeting. --- -# Quick Start: Integration as API +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Quick start: Integration as API **Time:** Under 10 minutes | **What you'll build:** An HTTP service that receives requests, calls an external API, and returns the response. ## Prerequisites -- [WSO2 Integrator extension installed](install.md) +- [WSO2 Integrator installed](install.md) ## Architecture -``` -Client Your Service External API - │ /hello:9090 apis.wso2.com - │ GET /greeting │ │ - │──────────────────────────►│ GET /mi-qsg/v1.0 │ - │ │───────────────────────►│ - │ │◄───────────────────────│ - │◄──────────────────────────│ {"message":"Hello"} │ - │ {"message":"Hello!!!"} │ │ -``` + -## Step 1: Create the Project +## Step 1: Create the project -1. Open the WSO2 Integrator sidebar in VS Code. -2. Click **Create New Integration**. -3. Enter the integration name (e.g., `HelloWorld`). -4. Click **Create Integration**. +1. Open WSO2 Integrator. +2. Select **Create New Integration**. +3. Enter the integration name (for example, `HelloWorld`). +4. Select **Create Integration**. -## Step 2: Add an HTTP Service +## Step 2: Add an HTTP service 1. In the design view, add an **HTTP Service** artifact. 2. Set the base path to `/hello` and port to `9090`. 3. Add a **GET** resource at the path `/greeting`. -## Step 3: Connect to an External API +## Step 3: Connect to an external API 1. Add an HTTP connection to `https://apis.wso2.com/zvdz/mi-qsg/v1.0`. 2. In the GET resource, invoke the external API and return its response. -In code, this looks like: + + ```ballerina import ballerina/http; @@ -58,9 +61,23 @@ service /hello on new http:Listener(9090) { } ``` -## Step 4: Run and Test + + + + + + + + +## Step 4: Run and test -1. Click **Run** in the toolbar (top-right corner). +1. Select **Run** in the toolbar. 2. Once the service starts, test with curl: ```bash @@ -73,11 +90,11 @@ Expected response: {"message": "Hello World!!!"} ``` -You can also use the built-in **Try It** panel in VS Code to test the endpoint interactively. +You can also use the built-in **Try It** panel in WSO2 Integrator to test the endpoint interactively. -## What's Next +## What's next -- [Quick Start: Automation](quick-start-automation.md) -- Build a scheduled job -- [Quick Start: AI Agent](quick-start-ai-agent.md) -- Build an intelligent agent -- [Quick Start: Event Integration](quick-start-event.md) -- React to messages from Kafka or RabbitMQ +- [Quick start: Automation](quick-start-automation.md) -- Build a scheduled job +- [Quick start: AI agent](quick-start-ai-agent.md) -- Build an intelligent agent +- [Quick start: Event integration](quick-start-event.md) -- React to messages from Kafka or RabbitMQ - [Tutorials](/docs/tutorials) -- End-to-end walkthroughs and patterns diff --git a/en/docs/get-started/quick-start-automation.md b/en/docs/get-started/quick-start-automation.md index efe3ec48..52bd247a 100644 --- a/en/docs/get-started/quick-start-automation.md +++ b/en/docs/get-started/quick-start-automation.md @@ -4,7 +4,12 @@ title: "Quick Start: Build an Automation" description: Create a scheduled automation that runs tasks on a timer. --- -# Quick Start: Build an Automation +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Quick start: Build an automation **Time:** Under 10 minutes | **What you'll build:** A scheduled automation that runs tasks on a timer or manual trigger. @@ -12,20 +17,30 @@ Automations are ideal for data synchronization, report generation, and routine m ## Prerequisites -- [WSO2 Integrator extension installed](install.md) +- [WSO2 Integrator installed](install.md) + +## Architecture -## Step 1: Create the Project + -1. Open the WSO2 Integrator sidebar in VS Code. -2. Click **Create New Integration**. -3. Enter the integration name (e.g., `MyAutomation`). +## Step 1: Create the project -## Step 2: Add an Automation Artifact +1. Open WSO2 Integrator. +2. Select **Create New Integration**. +3. Enter the integration name (for example, `MyAutomation`). + +## Step 2: Add an automation artifact 1. In the design view, add an **Automation** artifact. 2. The automation starts with an empty flow. -## Step 3: Add Logic +## Step 3: Add logic 1. Add a **Call Function** node to the flow. 2. Configure it with a simple expression: @@ -38,16 +53,19 @@ public function main() { } ``` -## Step 4: Run and Test +## Step 4: Run and test -1. Click **Run** in the toolbar (top-right corner). +1. Select **Run** in the toolbar. 2. The automation executes immediately and prints output to the terminal. 3. Check the terminal output for `Hello World`. -## Scheduling Automations +## Scheduling automations For production use, configure a cron schedule to trigger the automation periodically: + + + ```ballerina import ballerina/task; @@ -62,8 +80,22 @@ service on timer { } ``` -## What's Next + + + + + + + + +## What's next -- [Quick Start: Integration as API](quick-start-api.md) -- Build an HTTP service -- [Quick Start: Event Integration](quick-start-event.md) -- React to messages from brokers -- [Quick Start: AI Agent](quick-start-ai-agent.md) -- Build an intelligent agent +- [Quick start: Integration as API](quick-start-api.md) -- Build an HTTP service +- [Quick start: Event integration](quick-start-event.md) -- React to messages from brokers +- [Quick start: AI agent](quick-start-ai-agent.md) -- Build an intelligent agent diff --git a/en/docs/get-started/quick-start-data-service.md b/en/docs/get-started/quick-start-data-service.md index 1dc894df..936d48be 100644 --- a/en/docs/get-started/quick-start-data-service.md +++ b/en/docs/get-started/quick-start-data-service.md @@ -4,7 +4,12 @@ title: "Quick Start: Build a Data Service" description: Create a CRUD data service using bal persist in under 10 minutes. --- -# Build a Data Service +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Build a data service In this quick start, you'll create a data service that exposes CRUD operations over a database using `bal persist` — Ballerina's built-in data persistence layer. @@ -13,14 +18,24 @@ In this quick start, you'll create a data service that exposes CRUD operations o - [WSO2 Integrator set up](install.md) - A running database (MySQL, PostgreSQL, or H2 for quick testing) -## Step 1: Create a New Project +## Architecture + + + +## Step 1: Create a new project ```bash bal new data_service cd data_service ``` -## Step 2: Initialize Persistence +## Step 2: Initialize persistence ```bash bal persist init @@ -28,7 +43,7 @@ bal persist init This creates a `persist` directory with a model definition file. -## Step 3: Define Your Data Model +## Step 3: Define your data model Edit `persist/model.bal`: @@ -45,7 +60,7 @@ type Employee record {| |}; ``` -## Step 4: Generate the Client +## Step 4: Generate the client ```bash bal persist generate @@ -53,10 +68,13 @@ bal persist generate This generates type-safe client code for CRUD operations against your database. -## Step 5: Create the Service +## Step 5: Create the service Edit `main.bal`: + + + ```ballerina import ballerina/http; import ballerina/persist; @@ -94,7 +112,21 @@ service /employees on new http:Listener(port) { } ``` -## Step 6: Configure the Database + + + + + + + + +## Step 6: Configure the database Edit `Config.toml`: @@ -109,7 +141,7 @@ password = "" database = "employees_db" ``` -## Step 7: Run and Test +## Step 7: Run and test ```bash bal run @@ -130,7 +162,7 @@ curl -X POST http://localhost:8080/employees \ curl http://localhost:8080/employees/1 ``` -## Supported Data Stores +## Supported data stores `bal persist` supports seven data stores out of the box: @@ -144,8 +176,8 @@ curl http://localhost:8080/employees/1 | Redis | `ballerinax/persist.redis` | | In-Memory | Built-in | -## What's Next +## What's next -- [Data Persistence](../develop/integration-artifacts/data-persistence.md) — Deep dive into `bal persist` +- [Data persistence](../develop/integration-artifacts/data-persistence.md) — Deep dive into `bal persist` - [Services](../develop/integration-artifacts/services.md) — Advanced service configuration -- [Quick Start: Build an AI Agent](quick-start-ai-agent.md) — Add AI capabilities +- [Quick start: Build an AI agent](quick-start-ai-agent.md) — Add AI capabilities diff --git a/en/docs/get-started/quick-start-event.md b/en/docs/get-started/quick-start-event.md index 3b47bf13..fc3c79e0 100644 --- a/en/docs/get-started/quick-start-event.md +++ b/en/docs/get-started/quick-start-event.md @@ -4,7 +4,12 @@ title: "Quick Start: Event Integration" description: Build an event-driven integration that reacts to messages from a message broker. --- -# Quick Start: Event Integration +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Quick start: Event integration **Time:** Under 10 minutes | **What you'll build:** An event-driven integration that consumes messages from RabbitMQ and processes them. @@ -12,16 +17,26 @@ Event integrations are ideal for reactive workflows triggered by messages from K ## Prerequisites -- [WSO2 Integrator extension installed](install.md) +- [WSO2 Integrator installed](install.md) - A running RabbitMQ instance (or use Docker: `docker run -d -p 5672:5672 -p 15672:15672 rabbitmq:management`) -## Step 1: Create the Project +## Architecture + + -1. Open the WSO2 Integrator sidebar in VS Code. -2. Click **Create New Integration**. -3. Enter the integration name (e.g., `OrderProcessor`). +## Step 1: Create the project -## Step 2: Add an Event Integration Artifact +1. Open WSO2 Integrator. +2. Select **Create New Integration**. +3. Enter the integration name (for example, `OrderProcessor`). + +## Step 2: Add an event integration artifact 1. In the design view, add a **RabbitMQ** event integration artifact. 2. Configure the connection: @@ -31,10 +46,13 @@ Event integrations are ideal for reactive workflows triggered by messages from K - **Username:** `guest` - **Password:** `guest` -## Step 3: Add Message Processing Logic +## Step 3: Add message processing logic Add an `onMessage` handler to process incoming messages: + + + ```ballerina import ballerinax/rabbitmq; import ballerina/log; @@ -52,26 +70,40 @@ service on orderListener { } ``` -## Step 4: Run and Test + + + + + + + + +## Step 4: Run and test -1. Click **Run** in the toolbar. +1. Select **Run** in the toolbar. 2. The service starts listening for messages on the `Orders` queue. 3. Publish a test message to RabbitMQ using the management UI at `http://localhost:15672` or a client. 4. Check the terminal output for the logged message. -## Supported Event Sources +## Supported event sources | Broker | Ballerina Package | |---|---| -| **Apache Kafka** | `ballerinax/kafka` | -| **RabbitMQ** | `ballerinax/rabbitmq` | -| **MQTT** | `ballerinax/mqtt` | -| **Azure Service Bus** | `ballerinax/azure.servicebus` | -| **Salesforce** | `ballerinax/salesforce` | -| **GitHub Webhooks** | `ballerinax/github` | - -## What's Next - -- [Quick Start: File Integration](quick-start-file.md) -- Process files from FTP or local directories -- [Quick Start: Integration as API](quick-start-api.md) -- Build an HTTP service -- [Event Handlers](/docs/develop/integration-artifacts/event-handlers) -- Advanced event-driven patterns +| Apache Kafka | `ballerinax/kafka` | +| RabbitMQ | `ballerinax/rabbitmq` | +| MQTT | `ballerinax/mqtt` | +| Azure Service Bus | `ballerinax/azure.servicebus` | +| Salesforce | `ballerinax/salesforce` | +| GitHub Webhooks | `ballerinax/github` | + +## What's next + +- [Quick start: File integration](quick-start-file.md) -- Process files from FTP or local directories +- [Quick start: Integration as API](quick-start-api.md) -- Build an HTTP service +- [Event handlers](/docs/develop/integration-artifacts/event-handlers) -- Advanced event-driven patterns diff --git a/en/docs/get-started/quick-start-file.md b/en/docs/get-started/quick-start-file.md index 12a1f9b0..e4de5309 100644 --- a/en/docs/get-started/quick-start-file.md +++ b/en/docs/get-started/quick-start-file.md @@ -4,7 +4,12 @@ title: "Quick Start: File Integration" description: Process files from FTP, SFTP, or local directories. --- -# Quick Start: File Integration +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Quick start: File integration **Time:** Under 10 minutes | **What you'll build:** A file integration that watches a directory for new files, processes them, and writes the output. @@ -12,23 +17,36 @@ File integrations are ideal for batch uploads, scheduled file processing, and ET ## Prerequisites -- [WSO2 Integrator extension installed](install.md) +- [WSO2 Integrator installed](install.md) + +## Architecture -## Step 1: Create the Project + -1. Open the WSO2 Integrator sidebar in VS Code. -2. Click **Create New Integration**. -3. Enter the integration name (e.g., `FileProcessor`). +## Step 1: Create the project -## Step 2: Add a File Integration Artifact +1. Open WSO2 Integrator. +2. Select **Create New Integration**. +3. Enter the integration name (for example, `FileProcessor`). + +## Step 2: Add a file integration artifact 1. In the design view, add a **Directory Service** (for local files) or **FTP Service** (for remote files) artifact. 2. Configure the directory path to watch. -## Step 3: Process Incoming Files +## Step 3: Process incoming files Add logic to read and process files when they arrive: + + + ```ballerina import ballerina/file; import ballerina/io; @@ -54,23 +72,37 @@ service on dirListener { } ``` -## Step 4: Run and Test + + + + + + + + +## Step 4: Run and test -1. Click **Run** in the toolbar. +1. Select **Run** in the toolbar. 2. Drop a file into the watched directory (`/data/inbox`). 3. Verify the processed output appears in `/data/processed/`. -## Supported File Sources +## Supported file sources | Source | Transport | Use Case | |---|---|---| -| **Local directory** | File system | Development, on-premise batch processing | -| **FTP** | FTP | Legacy file exchange | -| **FTPS** | FTP over TLS | Secure legacy file exchange | -| **SFTP** | SSH File Transfer | Secure file exchange | +| Local directory | File system | Development, on-premise batch processing | +| FTP | FTP | Legacy file exchange | +| FTPS | FTP over TLS | Secure legacy file exchange | +| SFTP | SSH File Transfer | Secure file exchange | -## What's Next +## What's next -- [Quick Start: Automation](quick-start-automation.md) -- Build scheduled jobs -- [Quick Start: Integration as API](quick-start-api.md) -- Build an HTTP service -- [File Handlers](/docs/develop/integration-artifacts/file-handlers) -- Advanced file processing patterns +- [Quick start: Automation](quick-start-automation.md) -- Build scheduled jobs +- [Quick start: Integration as API](quick-start-api.md) -- Build an HTTP service +- [File handlers](/docs/develop/integration-artifacts/file-handlers) -- Advanced file processing patterns diff --git a/en/static/img/develop/integration-artifacts/event/kafka/listener-config-1.png b/en/static/img/develop/integration-artifacts/event/kafka/listener-config-1.png new file mode 100644 index 00000000..5aebf5da Binary files /dev/null and b/en/static/img/develop/integration-artifacts/event/kafka/listener-config-1.png differ diff --git a/en/static/img/develop/integration-artifacts/event/kafka/service-config-1.png b/en/static/img/develop/integration-artifacts/event/kafka/service-config-1.png new file mode 100644 index 00000000..5aebf5da Binary files /dev/null and b/en/static/img/develop/integration-artifacts/event/kafka/service-config-1.png differ diff --git a/en/static/img/develop/integration-artifacts/event/kafka/step-1.png b/en/static/img/develop/integration-artifacts/event/kafka/step-1.png new file mode 100644 index 00000000..68020a00 Binary files /dev/null and b/en/static/img/develop/integration-artifacts/event/kafka/step-1.png differ diff --git a/en/static/img/develop/integration-artifacts/event/kafka/step-2.png b/en/static/img/develop/integration-artifacts/event/kafka/step-2.png new file mode 100644 index 00000000..70ad32d4 Binary files /dev/null and b/en/static/img/develop/integration-artifacts/event/kafka/step-2.png differ diff --git a/en/static/img/develop/integration-artifacts/event/kafka/step-3.png b/en/static/img/develop/integration-artifacts/event/kafka/step-3.png new file mode 100644 index 00000000..608b3716 Binary files /dev/null and b/en/static/img/develop/integration-artifacts/event/kafka/step-3.png differ diff --git a/en/static/img/develop/integration-artifacts/event/kafka/step-4.png b/en/static/img/develop/integration-artifacts/event/kafka/step-4.png new file mode 100644 index 00000000..652cc6c4 Binary files /dev/null and b/en/static/img/develop/integration-artifacts/event/kafka/step-4.png differ diff --git a/en/static/img/develop/integration-artifacts/event/kafka/step-creation-form.png b/en/static/img/develop/integration-artifacts/event/kafka/step-creation-form.png new file mode 100644 index 00000000..22f9b260 Binary files /dev/null and b/en/static/img/develop/integration-artifacts/event/kafka/step-creation-form.png differ diff --git a/en/static/img/develop/integration-artifacts/service/http-service/configure-panel.png b/en/static/img/develop/integration-artifacts/service/http-service/configure-panel.png new file mode 100644 index 00000000..b497ad82 Binary files /dev/null and b/en/static/img/develop/integration-artifacts/service/http-service/configure-panel.png differ diff --git a/en/static/img/develop/integration-artifacts/service/http-service/service-designer-overview.png b/en/static/img/develop/integration-artifacts/service/http-service/service-designer-overview.png new file mode 100644 index 00000000..9fd4f9c7 Binary files /dev/null and b/en/static/img/develop/integration-artifacts/service/http-service/service-designer-overview.png differ diff --git a/en/static/img/develop/integration-artifacts/service/http-service/step-1.png b/en/static/img/develop/integration-artifacts/service/http-service/step-1.png new file mode 100644 index 00000000..9a70498a Binary files /dev/null and b/en/static/img/develop/integration-artifacts/service/http-service/step-1.png differ diff --git a/en/static/img/develop/integration-artifacts/service/http-service/step-2.png b/en/static/img/develop/integration-artifacts/service/http-service/step-2.png new file mode 100644 index 00000000..f9301668 Binary files /dev/null and b/en/static/img/develop/integration-artifacts/service/http-service/step-2.png differ diff --git a/en/static/img/develop/integration-artifacts/service/http-service/step-3.png b/en/static/img/develop/integration-artifacts/service/http-service/step-3.png new file mode 100644 index 00000000..67e375d8 Binary files /dev/null and b/en/static/img/develop/integration-artifacts/service/http-service/step-3.png differ diff --git a/en/static/img/develop/integration-artifacts/service/http-service/step-4.png b/en/static/img/develop/integration-artifacts/service/http-service/step-4.png new file mode 100644 index 00000000..4529bdad Binary files /dev/null and b/en/static/img/develop/integration-artifacts/service/http-service/step-4.png differ diff --git a/en/static/img/develop/integration-artifacts/service/http-service/step-creation-form.png b/en/static/img/develop/integration-artifacts/service/http-service/step-creation-form.png new file mode 100644 index 00000000..4b2c7ddb Binary files /dev/null and b/en/static/img/develop/integration-artifacts/service/http-service/step-creation-form.png differ diff --git a/en/static/img/get-started/quick-start-ai-agent/ai-agent-dark.svg b/en/static/img/get-started/quick-start-ai-agent/ai-agent-dark.svg new file mode 100644 index 00000000..aa52966b --- /dev/null +++ b/en/static/img/get-started/quick-start-ai-agent/ai-agent-dark.svg @@ -0,0 +1,4 @@ + + + +Internal.size.36...cog...size..size.36...person...size..size.36...cog...size..size.36...cloud...size.ClientGraphQL Servicelocalhost:8080LLMOpenAI.size.36...cog...size.mutation Task(query)prompt + toolsresponse{ data: { task: "..." } } \ No newline at end of file diff --git a/en/static/img/get-started/quick-start-ai-agent/ai-agent-light.svg b/en/static/img/get-started/quick-start-ai-agent/ai-agent-light.svg new file mode 100644 index 00000000..d901205a --- /dev/null +++ b/en/static/img/get-started/quick-start-ai-agent/ai-agent-light.svg @@ -0,0 +1,4 @@ + + + +Internal.size.36...cog...size..size.36...person...size..size.36...cog...size..size.36...cloud...size.ClientGraphQL Servicelocalhost:8080LLMOpenAI.size.36...cog...size.mutation Task(query)prompt + toolsresponse{ data: { task: "..." } } \ No newline at end of file diff --git a/en/static/img/get-started/quick-start-ai-agent/design-view-dark.png b/en/static/img/get-started/quick-start-ai-agent/design-view-dark.png new file mode 100644 index 00000000..c0990abe Binary files /dev/null and b/en/static/img/get-started/quick-start-ai-agent/design-view-dark.png differ diff --git a/en/static/img/get-started/quick-start-ai-agent/design-view-light.png b/en/static/img/get-started/quick-start-ai-agent/design-view-light.png new file mode 100644 index 00000000..2fff7723 Binary files /dev/null and b/en/static/img/get-started/quick-start-ai-agent/design-view-light.png differ diff --git a/en/static/img/get-started/quick-start-api/api-dark.svg b/en/static/img/get-started/quick-start-api/api-dark.svg new file mode 100644 index 00000000..96ccf7cd --- /dev/null +++ b/en/static/img/get-started/quick-start-api/api-dark.svg @@ -0,0 +1,4 @@ + + + +Internal NetworkExternal.size.36...cog...size..size.36...cloud...size..size.36...person...size..size.36...cog...size..size.36...cloud...size.ClientClientYour Servicehello:9090Your Servicehello:9090External APIapis.wso2.comExternal APIapis.wso2.com.size.36...cog...size..size.36...cloud...size.GET/greetingGET/mi-qsg/v1.0{"message":"Hello"}{"message":"Hello"} \ No newline at end of file diff --git a/en/static/img/get-started/quick-start-api/api-light.svg b/en/static/img/get-started/quick-start-api/api-light.svg new file mode 100644 index 00000000..766091c2 --- /dev/null +++ b/en/static/img/get-started/quick-start-api/api-light.svg @@ -0,0 +1,4 @@ + + + +Internal NetworkExternal.size.36...cog...size..size.36...cloud...size..size.36...person...size..size.36...cog...size..size.36...cloud...size.ClientClientYour Servicehello:9090Your Servicehello:9090External APIapis.wso2.comExternal APIapis.wso2.com.size.36...cog...size..size.36...cloud...size.GET/greetingGET/mi-qsg/v1.0{"message":"Hello"}{"message":"Hello"} \ No newline at end of file diff --git a/en/static/img/get-started/quick-start-api/design-view-dark.png b/en/static/img/get-started/quick-start-api/design-view-dark.png new file mode 100644 index 00000000..8587534f Binary files /dev/null and b/en/static/img/get-started/quick-start-api/design-view-dark.png differ diff --git a/en/static/img/get-started/quick-start-api/design-view-light.png b/en/static/img/get-started/quick-start-api/design-view-light.png new file mode 100644 index 00000000..8f244e49 Binary files /dev/null and b/en/static/img/get-started/quick-start-api/design-view-light.png differ diff --git a/en/static/img/get-started/quick-start-automation/automation-dark.svg b/en/static/img/get-started/quick-start-automation/automation-dark.svg new file mode 100644 index 00000000..47a791f1 --- /dev/null +++ b/en/static/img/get-started/quick-start-automation/automation-dark.svg @@ -0,0 +1,4 @@ + + + +Internal.size.36...cog...size..size.36...clock...size..size.36...cog...size..size.36...terminal...size.Timertask:ListenerAutomationServiceTerminal(io).size.36...cog...size.onTrigger()println("Hello World") \ No newline at end of file diff --git a/en/static/img/get-started/quick-start-automation/automation-light.svg b/en/static/img/get-started/quick-start-automation/automation-light.svg new file mode 100644 index 00000000..408cc172 --- /dev/null +++ b/en/static/img/get-started/quick-start-automation/automation-light.svg @@ -0,0 +1,4 @@ + + + +Internal.size.36...cog...size..size.36...clock...size..size.36...cog...size..size.36...terminal...size.Timertask:ListenerAutomationServiceTerminal(io).size.36...cog...size.onTrigger()println("Hello World") \ No newline at end of file diff --git a/en/static/img/get-started/quick-start-automation/design-view-dark.png b/en/static/img/get-started/quick-start-automation/design-view-dark.png new file mode 100644 index 00000000..df284bd3 Binary files /dev/null and b/en/static/img/get-started/quick-start-automation/design-view-dark.png differ diff --git a/en/static/img/get-started/quick-start-automation/design-view-light.png b/en/static/img/get-started/quick-start-automation/design-view-light.png new file mode 100644 index 00000000..edbca419 Binary files /dev/null and b/en/static/img/get-started/quick-start-automation/design-view-light.png differ diff --git a/en/static/img/get-started/quick-start-data-service/data-service-dark.svg b/en/static/img/get-started/quick-start-data-service/data-service-dark.svg new file mode 100644 index 00000000..0cab1156 --- /dev/null +++ b/en/static/img/get-started/quick-start-data-service/data-service-dark.svg @@ -0,0 +1,4 @@ + + + +Internal System.size.36...cog...size..size.36...person...size..size.36...cog...size..size.36...hard-drive...size.ClientEmployee Service/employees:8080Database.size.36...cog...size.GET /employees/1Query Employee (ID: 1)Employee RecordJSON Response \ No newline at end of file diff --git a/en/static/img/get-started/quick-start-data-service/data-service-light.svg b/en/static/img/get-started/quick-start-data-service/data-service-light.svg new file mode 100644 index 00000000..60ac6e84 --- /dev/null +++ b/en/static/img/get-started/quick-start-data-service/data-service-light.svg @@ -0,0 +1,4 @@ + + + +Internal System.size.36...cog...size..size.36...person...size..size.36...cog...size..size.36...hard-drive...size.ClientEmployee Service/employees:8080Database.size.36...cog...size.GET /employees/1Query Employee (ID: 1)Employee RecordJSON Response \ No newline at end of file diff --git a/en/static/img/get-started/quick-start-data-service/design-view-dark.png b/en/static/img/get-started/quick-start-data-service/design-view-dark.png new file mode 100644 index 00000000..1093d8c4 Binary files /dev/null and b/en/static/img/get-started/quick-start-data-service/design-view-dark.png differ diff --git a/en/static/img/get-started/quick-start-data-service/design-view-light.png b/en/static/img/get-started/quick-start-data-service/design-view-light.png new file mode 100644 index 00000000..177629ec Binary files /dev/null and b/en/static/img/get-started/quick-start-data-service/design-view-light.png differ diff --git a/en/static/img/get-started/quick-start-event/design-view-dark.png b/en/static/img/get-started/quick-start-event/design-view-dark.png new file mode 100644 index 00000000..7d289077 Binary files /dev/null and b/en/static/img/get-started/quick-start-event/design-view-dark.png differ diff --git a/en/static/img/get-started/quick-start-event/design-view-light.png b/en/static/img/get-started/quick-start-event/design-view-light.png new file mode 100644 index 00000000..5b8dc17e Binary files /dev/null and b/en/static/img/get-started/quick-start-event/design-view-light.png differ diff --git a/en/static/img/get-started/quick-start-event/event-dark.svg b/en/static/img/get-started/quick-start-event/event-dark.svg new file mode 100644 index 00000000..e0a8306c --- /dev/null +++ b/en/static/img/get-started/quick-start-event/event-dark.svg @@ -0,0 +1,4 @@ + + + +Internal.size.36...cog...size..size.36...inbox...size..size.36...cog...size..size.36...list...size.RabbitMQQueue: OrdersorderListenerServiceLogger.size.36...cog...size.onMessage(rabbitmq:AnydataMessage)printInfo("Received order") \ No newline at end of file diff --git a/en/static/img/get-started/quick-start-event/event-light.svg b/en/static/img/get-started/quick-start-event/event-light.svg new file mode 100644 index 00000000..f66dc51e --- /dev/null +++ b/en/static/img/get-started/quick-start-event/event-light.svg @@ -0,0 +1,4 @@ + + + +Internal.size.36...cog...size..size.36...inbox...size..size.36...cog...size..size.36...list...size.RabbitMQQueue: OrdersorderListenerServiceLogger.size.36...cog...size.onMessage(rabbitmq:AnydataMessage)printInfo("Received order") \ No newline at end of file diff --git a/en/static/img/get-started/quick-start-file/design-view-dark.png b/en/static/img/get-started/quick-start-file/design-view-dark.png new file mode 100644 index 00000000..d1319160 Binary files /dev/null and b/en/static/img/get-started/quick-start-file/design-view-dark.png differ diff --git a/en/static/img/get-started/quick-start-file/design-view-light.png b/en/static/img/get-started/quick-start-file/design-view-light.png new file mode 100644 index 00000000..03a1db61 Binary files /dev/null and b/en/static/img/get-started/quick-start-file/design-view-light.png differ diff --git a/en/static/img/get-started/quick-start-file/file-dark.svg b/en/static/img/get-started/quick-start-file/file-dark.svg new file mode 100644 index 00000000..61efb4b6 --- /dev/null +++ b/en/static/img/get-started/quick-start-file/file-dark.svg @@ -0,0 +1,4 @@ + + + +Internal.size.36...cog...size..size.36...folder...size..size.36...cog...size..size.36...folder...size.Input Directory/data/inboxdirListenerServiceOutput Directory/data/processed/.size.36...cog...size.onCreate(file:FileEvent)io:fileReadString()CSV contentio:fileWriteString(content) \ No newline at end of file diff --git a/en/static/img/get-started/quick-start-file/file-light.svg b/en/static/img/get-started/quick-start-file/file-light.svg new file mode 100644 index 00000000..5298ee24 --- /dev/null +++ b/en/static/img/get-started/quick-start-file/file-light.svg @@ -0,0 +1,4 @@ + + + +Internal.size.36...cog...size..size.36...folder...size..size.36...cog...size..size.36...folder...size.Input Directory/data/inboxdirListenerServiceOutput Directory/data/processed/.size.36...cog...size.onCreate(file:FileEvent)io:fileReadString()CSV contentio:fileWriteString(content) \ No newline at end of file