DEV Community

Peter + AI
Peter + AI

Posted on

Uniface Session Services: The Unsung Heroes of Business Logic πŸ¦Έβ€β™‚οΈπŸ’»

Are you a Uniface developer or simply maintaining a legacy system and wondering, "What exactly does this headless component do?" πŸ€”

In this post, I'll break down the Session Service in Uniface, explain why it's crucial for clean architecture, and how it helps you separate concerns effectively. Let's dive in! πŸš€


What is a Session Service? 🧐

A Session Service (SSV) in Uniface is a specialized component designed to encapsulate complex business logic without any user interface (UI). Think of it as the "engine room" or "Controller" of a specific business process. βš™οΈ

Unlike simple Entity Services (which typically manage CRUD operations for a single database entity), a Session Service acts as a coordinator. It manages logic that spans multiple entities, handles transaction boundaries, and executes specific tasks.

Key Characteristics:

  • Headless: It has no forms, windows, or widgets. It runs entirely in the background. πŸ‘»
  • Task-Oriented: It is built to handle specific operations like "Process Order" or "Calculate End-of-Month Report".
  • Stateless (mostly): In modern web contexts (like using the Uniface Web Application Server), Session Services are often designed to be instantiated for a single request and then destroyed. πŸ’¨
  • Transaction Controller: It often takes responsibility for the commit and rollback commands to ensure data integrity across multiple tables. πŸ›‘οΈ

The Problem: Logic in the UI Layer 🍝❌

Imagine you have a "Buy Now" button in a DSP (Dynamic Server Page) or a Form. A common mistake is to put all the processing logic directly into the button's detail trigger:

  • Check stock availability πŸ“¦
  • Create a header record in the ORDERS entity πŸ“
  • Loop through a list to create ORDER_LINES πŸ”„
  • Update the CUSTOMER credit limit πŸ’³
  • Send a confirmation email πŸ“§

Why is this problematic?

  • Lack of Reusability: If you need to trigger the same process from a different part of the system (e.g., a batch job or a REST API), you have to duplicate the code. 😱
  • Testing Difficulties: Logic embedded in UI triggers is hard to test independently.
  • Maintenance Headaches: Your form code becomes bloated, making it difficult to read and maintain.

The Solution: Encapsulate with Session Services βœ…

By moving that logic into a dedicated Session Service component (e.g., SVC_ORDER_PROCESS), you clean up your architecture significantly. Your UI trigger becomes a simple call:

; Button "Buy Now" Trigger
activate "SVC_ORDER_PROCESS".createOrder(in_CustomerID, in_CartID, out_Status)
Enter fullscreen mode Exit fullscreen mode

This approach decouples the process from the presentation. ✨

Code Example: The "Create Order" Operation πŸ›’

Here is a simplified example of what the ProcScript inside a Session Service operation might look like.

Component: SVC_ORDER_PROCESS

Operation: createOrder

entry createOrder
    params
        string  pCustomerID : IN
        string  pItemList   : IN
        numeric pStatus     : OUT
    endparams

    variables
        numeric vTotalAmount
        string  vItem
    endvariables

    ; 1. Validate Customer
    activate "SVC_CUSTOMER".checkCredit(pCustomerID, pStatus)
    if (pStatus < 0) return -1

    ; 2. Create Order Header
    clear/e "ORDERS"
    ORDERS.CUST_ID = pCustomerID
    ORDERS.DATE    = $date

    ; 3. Process Items (Iterating through the list)
    getitem/id vItem, pItemList, 1
    while ($status > 0)
        creocc "ORDER_LINES"
        ORDER_LINES.ITEM_ID = vItem
        ; ... logic to calculate price and discounts ...

        getitem/id vItem, pItemList, $loopcounter + 1
    endwhile

    ; 4. Transaction Management
    commit
    if ($status < 0)
        rollback
        pStatus = -99
        return -99
    endif

    pStatus = 1 ; Success! πŸŽ‰
    return 0
end
Enter fullscreen mode Exit fullscreen mode

Common Pitfalls to Avoid ⚠️

  • Assuming State Persistence: In a web environment, don't assume the service remembers variables from a previous call. Always pass all necessary context (like Session IDs or current status) as parameters! πŸ”„
  • Interactive Commands: Never use askmess or other interactive commands inside a Session Service. Since it runs on the server (often headless), the process will hang indefinitely waiting for user input that can never happen! πŸ›‘
  • Locking Issues: Be mindful of record locking. If your service locks data and takes a long time to complete without committing, it can block other users. ⏳

Conclusion 🎯

Session Services are essential for building scalable and maintainable Uniface applications. They keep your code DRY (Don't Repeat Yourself), allow for better separation of concerns, and make your application logic testable.

Whether you are modernizing an old system or building a new service-oriented architecture, mastering the Session Service is key to professional Uniface development.

Happy Coding! πŸ’»βœ¨

Top comments (0)