Web Application Development

Chapter 6
Server-Side Programming and Application Architecture

Bachelors Program in Computer Science Engineering
Web Application Development   •   Bachelor

Server-Side Programming and Application Architecture

Introduction

A web application is more than a collection of browser pages. The browser presents an interface, but the server commonly performs routing, authentication, validation, business processing, data access, logging, and response generation. Server-side programming is therefore the discipline of designing software that receives requests, applies rules securely and consistently, communicates with data stores or external services, and returns responses such as HTML, JSON, files, or redirects.

A well-designed server application must satisfy several competing goals: correctness, security, maintainability, performance, observability, and operational simplicity. These goals are influenced not only by programming language and framework, but also by application architecture—the structural arrangement of components and their dependencies.

This chapter uses HTTP-based applications as its main context. Examples use framework-neutral pseudocode resembling modern web frameworks.

Learning Objectives

By the end of this chapter, students should be able to:

  1. Explain the request–response lifecycle of a server-side application.
  2. Implement and evaluate routing, middleware, templates, validation, authentication, configuration, logging, and error handling.
  3. Distinguish authentication from authorization and apply both safely.
  4. Compare monolithic, layered, MVC, clean, event-driven, microservice, and serverless architectures.
  5. Select an appropriate architecture for a given organizational and technical context.
  6. Analyze a server-side design for maintainability, security, reliability, and operational risk.

1. The Server-Side Request Lifecycle

A typical request passes through several stages:

  1. A client resolves a domain name and establishes a connection, normally using HTTPS.
  2. A reverse proxy or load balancer may terminate TLS and forward the request.
  3. The web server or application runtime parses the HTTP request.
  4. Middleware performs cross-cutting operations such as request identification, authentication, or rate limiting.
  5. A router selects a handler using the HTTP method and URL pattern.
  6. The handler validates input and invokes application services.
  7. Services apply business rules and use repositories or external clients.
  8. The application produces a response.
  9. Error handling, logging, metrics, and tracing record the result.
  10. The server sends the response to the client.

The HTTP method communicates intended semantics. GET generally retrieves a representation, POST creates a subordinate resource or triggers an operation, PUT replaces a resource, PATCH partially updates a resource, and DELETE removes a resource. Safe methods should not intentionally change server state; idempotent methods produce the same intended effect when repeated, although responses may differ.

A request should not be trusted merely because it arrived at the server. URL parameters, headers, cookies, form data, JSON bodies, and uploaded files are all untrusted inputs.

2. Routing and Controllers

Routing maps an incoming method and path to executable application code. A route may contain static segments and parameters:

GET /products              → listProducts
GET /products/:id          → showProduct
POST /products             → createProduct
PATCH /products/:id        → updateProduct

A route handler, often called a controller, should coordinate rather than contain the entire application. It normally performs four tasks: obtain request data, invoke an application service, select a response, and translate known failures into HTTP responses.

function createProduct(request, response) {
    input = validateCreateProduct(request.body)
    product = productService.create(input, request.user.id)
    return response.status(201).json(productView(product))
}

Route specificity and ordering matter in frameworks that match routes sequentially. A general route such as /products/:id should not accidentally capture a special route such as /products/search. Route names should be stable, meaningful, and consistent with the resource model.

A controller should not directly construct SQL, implement password hashing, or contain complex pricing rules. Such responsibilities belong in appropriate lower layers.

3. Middleware

Middleware is software positioned between the incoming request and the final handler. It can inspect or transform a request, terminate processing, or pass control onward.

Common middleware includes:

  • request logging and correlation identifiers;
  • JSON and form-body parsing;
  • CORS policy enforcement;
  • authentication and authorization checks;
  • rate limiting;
  • input-size limits;
  • security headers;
  • static-file serving;
  • centralized error handling.

A conceptual middleware chain is:

request
  → request ID
  → security headers
  → body parser
  → authentication
  → authorization
  → router
  → controller
  → response

Middleware order is significant. Authentication must occur before authorization. Error middleware must be able to observe failures produced by downstream components. A body parser should enforce reasonable size limits before accepting large payloads.

Middleware should remain focused. A single component that performs logging, database access, authorization, and response formatting is difficult to test and reuse.

4. Templates and Response Generation

Template engines generate HTML by combining a presentation template with data. A template might contain:

<h1>{{ product.name }}</h1>
<p>{{ product.description }}</p>

The engine should escape output by default. Escaping converts characters such as < and & into safe representations, reducing cross-site scripting (XSS) risk. Raw HTML insertion should be exceptional, reviewed, and applied only to trusted or sanitized content.

Templates should express presentation decisions, not business policy. For example, a template may conditionally display a button based on a view model, while the server must independently enforce whether the user is allowed to perform the action. Hiding a button is not authorization.

Server-rendered applications may use the Post/Redirect/Get pattern: after a successful form submission, the server redirects to a GET page. This prevents accidental resubmission when the user refreshes the browser.

5. Validation and Data Integrity

Validation determines whether input is acceptable. It has at least three dimensions:

  • Syntactic validation: Is the value the correct type and format?
  • Semantic validation: Is it meaningful, such as a valid date range?
  • Business validation: Is it permitted by domain rules, such as a credit limit?

Client-side validation improves usability, but server-side validation is authoritative because clients can be modified or bypassed.

A validation result should identify fields and actionable messages without exposing internal implementation details. Validation rules should be centralized or shared where practical, but duplication may be justified when client and server have different responsibilities.

Validation does not replace parameterized database queries. A value that passes a format check may still be dangerous if concatenated into SQL. Use prepared statements or an ORM’s parameter binding:

SELECT * FROM users WHERE email = :email

Database constraints—such as NOT NULL, UNIQUE, FOREIGN KEY, and CHECK constraints—provide a second line of defense. Application validation improves user feedback; database constraints protect integrity under concurrency and against faulty application code.

6. Authentication and Authorization

Authentication answers “Who is the subject?” Authorization answers “What may that subject do?” Confusing these concepts is a common security defect.

A secure password workflow stores a slow, salted password hash rather than the password itself. During login, the supplied password is hashed using the stored parameters and compared using a suitable password-verification function. Modern password-hashing algorithms should be configured according to current security guidance and periodically reviewed.

Session-based authentication stores a session identifier in a cookie; the server associates that identifier with session state. Important cookie attributes include:

  • Secure: send the cookie only over HTTPS;
  • HttpOnly: prevent ordinary client-side scripts from reading it;
  • SameSite: reduce cross-site request risks;
  • appropriate expiration and scope settings.

Token-based authentication places claims in a signed token. Signature verification proves that the token was issued by a trusted authority and was not altered; it does not automatically make the token confidential. Sensitive data should not be placed in readable token payloads unless encryption and appropriate controls are used.

Authorization should be enforced on the server at the resource and operation level. Role-based access control assigns permissions through roles, while attribute- or policy-based access control evaluates properties such as ownership, department, time, or resource classification.

A secure login system also considers multi-factor authentication, account lockout or throttling, credential recovery, session invalidation, audit records, and protection against user enumeration. Error messages should not reveal whether an email address is registered.

7. Configuration and Secrets

Configuration includes values that vary between environments: database addresses, feature flags, timeout values, logging levels, and external-service endpoints. Secrets include passwords, API keys, signing keys, and certificates.

Configuration should be supplied through environment-specific mechanisms rather than hard-coded in source code. Secrets should be stored in a managed secret store or protected deployment system, not in public repositories. A startup process should validate required configuration and fail clearly when essential values are missing.

Configuration should be typed and documented. For example, a timeout must be interpreted consistently as milliseconds or seconds. Default values should be safe, and production settings should not silently fall back to development behavior.

8. Logging, Metrics, and Error Handling

Logging records events for diagnosis, security review, and operational learning. A useful structured log commonly includes timestamp, severity, service name, request or correlation ID, event name, duration, and relevant non-sensitive context.

Never log passwords, session tokens, complete payment-card data, or unnecessary personal information. Log access should itself be controlled.

Metrics summarize behavior numerically. Important web metrics include request rate, error rate, latency percentiles, saturation, queue depth, and resource utilization. The mean latency alone can conceal slow requests; the 95th percentile describes a value at or below which approximately 95% of observations fall in the measured sample.

Tracing follows a request across services and external calls. Correlation IDs connect logs, while distributed traces provide timing and dependency relationships.

Error handling should distinguish:

  • expected client errors, such as malformed input or forbidden actions;
  • expected domain failures, such as insufficient inventory;
  • infrastructure failures, such as database unavailability;
  • programmer defects, such as null-reference errors.

A consistent API error shape may include a stable error code, human-readable message, field details where appropriate, and a correlation ID. Production responses should avoid stack traces and SQL statements. Internally, the full diagnostic context should be recorded securely.

HTTP status codes should communicate broad outcomes: 2xx success, 3xx redirection, 4xx client-side request problems, and 5xx server-side failures. Status codes do not replace a useful application-level error contract.

9. Architectural Models

Architecture determines how responsibilities are divided and how components communicate. No architecture is universally superior; suitability depends on team size, domain complexity, scaling characteristics, compliance needs, and operational capability.

9.1 Monolithic Architecture

A monolith is deployed as one application unit. It may still have strong internal modularity. Advantages include simple deployment, straightforward local development, and transactions across modules. Disadvantages include coordinated releases, a large failure domain, and the possibility that a small change requires redeploying the whole application.

A monolith is often an appropriate starting point for a small team or a coherent domain. “Monolithic” does not necessarily mean poorly designed.

9.2 Layered Architecture

A conventional layered system separates presentation, application or service logic, domain logic, and data access:

Presentation → Application Services → Domain → Repositories → Database

Layers clarify responsibilities and support testing. However, strict layering can produce excessive pass-through code or cause the domain to become dependent on database details if boundaries are poorly enforced.

9.3 Model–View–Controller

MVC separates the model, view, and controller. The model represents data and domain behavior, the view presents output, and the controller coordinates requests. MVC is particularly useful for server-rendered web applications, but frameworks often use the term loosely. Teams must define responsibilities precisely rather than assuming that an MVC label guarantees good design.

9.4 Clean Architecture

Clean architecture places business rules near the center and infrastructure at the outside. Dependencies point inward toward stable policy. Use cases communicate through interfaces, allowing databases, web frameworks, and external services to be replaced or tested independently.

Its advantages include testability and protection of domain logic. Its costs include additional abstractions and design effort. It is most valuable when business rules are substantial or long-lived.

9.5 Event-Driven Architecture

In an event-driven system, a producer publishes an event such as OrderPlaced, and one or more consumers react asynchronously. Producers and consumers are decoupled in time and sometimes in deployment.

Benefits include scalability, integration flexibility, and resilience to temporary consumer unavailability. Challenges include eventual consistency, duplicate delivery, ordering, schema evolution, monitoring, and more difficult debugging. Consumers should generally be idempotent: processing the same event twice should not create an incorrect result.

9.6 Microservices

Microservices divide an application into independently deployable services, commonly organized around business capabilities. Each service may own its data and expose an explicit contract.

Potential benefits include team autonomy, selective scaling, and independent release cycles. Costs include network failure, distributed transactions, operational complexity, data duplication, versioned contracts, and increased observability requirements. Microservices are not a guaranteed solution to poor modularity.

9.7 Serverless Architecture

Serverless platforms execute functions or managed services without requiring the team to administer persistent servers directly. Billing often relates to invocations, execution time, or provisioned capacity. Serverless can reduce operational overhead and support elastic workloads.

Limitations include cold-start latency, execution limits, vendor coupling, statelessness requirements, and complexity in coordinating workflows. Serverless is an operational model, not a substitute for sound domain design.

Architectural Comparison

ModelMain strengthMain riskSuitable context
MonolithSimple deploymentLarge release unitSmall or coherent systems
LayeredClear responsibility boundariesPass-through layersConventional business applications
MVCEffective request-to-view organizationBlurred responsibilitiesServer-rendered web systems
CleanTestable, framework-independent rulesAbstraction overheadComplex, durable domains
Event-drivenLoose temporal couplingEventual consistencyIntegration and asynchronous workflows
MicroservicesIndependent deployment and scalingDistributed-systems complexityLarge teams and bounded capabilities
ServerlessLow infrastructure administrationPlatform and execution constraintsVariable, event-based workloads

10. Applied Case: University Equipment-Loan Service

The following is an illustrative case.

Background

A university library lends cameras, laptops, and laboratory equipment. Its initial application is a monolith with server-rendered pages and a relational database. Students report duplicate reservations, staff cannot easily investigate failures, and an external email provider occasionally delays notifications.

Problem Analysis

The reservation process contains several steps: authenticate the student, validate dates, verify availability, create a reservation, and send confirmation. The original design performs all steps synchronously in one controller. Two simultaneous requests can both observe an item as available unless the database transaction protects the operation. Email-provider failure also causes the reservation request to fail, even when the reservation was successfully stored.

Approach

The team retains the monolith but introduces internal layers. A controller validates the request and invokes a reservation use case. The use case performs availability checks within a database transaction and relies on a uniqueness or exclusion constraint appropriate to the database model. After committing the reservation, it publishes a ReservationCreated event to a durable queue. A notification worker consumes the event and sends email. The worker records delivery status and retries temporary failures with a bounded policy.

The application adds a request ID to every log entry, structured audit records for reservation changes, and a standard error response. Authorization rules ensure that students can view their own reservations while staff can manage all equipment. Configuration separates development, test, and production endpoints, and email credentials are placed in a secret store.

Outcome

The reservation operation no longer depends on immediate email delivery. Database constraints protect against duplicate allocation, while asynchronous notification improves resilience. The system remains deployable as one application plus a worker, avoiding premature microservice decomposition.

Learning Points

  1. Architectural improvement does not always require microservices.
  2. Database integrity and application validation address different failure modes.
  3. Events are useful when work can be completed asynchronously.
  4. Authorization must be expressed as a server-side policy.
  5. Observability is part of application design, not an afterthought.

11. Security, Ethics, and Governance

Server-side developers handle identity, personal data, and institutional records. They should apply least privilege, data minimization, secure defaults, and defense in depth. Privacy obligations may require notice, purpose limitation, retention controls, access rights, breach response, and deletion procedures, depending on jurisdiction and institutional policy.

Accessibility and fairness also matter. Error messages should be understandable, authentication alternatives should be considered for users with disabilities, and automated decisions should be reviewable where they affect access to services.

Dependency management is a governance responsibility. Teams should inventory libraries, patch known vulnerabilities, verify package sources, and review licenses. Security testing should include code review, dependency scanning, automated tests, penetration testing where appropriate, and threat modeling.

12. Best Practices and Contemporary Directions

Effective server-side engineering commonly follows these practices:

  • keep business rules independent of transport details;
  • validate at trust boundaries;
  • use parameterized data access;
  • enforce authorization on every protected operation;
  • make error contracts consistent;
  • make asynchronous consumers idempotent;
  • use health checks, metrics, logs, and traces together;
  • test both successful and failure paths;
  • automate deployment and configuration validation;
  • document API contracts and architectural decisions.

Contemporary development increasingly combines API-first design, automated security checks, infrastructure as code, containerized deployment, managed cloud services, and AI-assisted coding. AI-generated code must be reviewed for insecure defaults, licensing concerns, hallucinated APIs, privacy leakage, and inadequate tests. Human developers remain responsible for architecture, verification, and production behavior.

Chapter Summary

Server-side programming manages the trusted processing environment of a web application. Requests pass through middleware, routing, controllers, validation, application services, data access, response generation, and observability mechanisms. Templates must escape untrusted output, and server-side validation and authorization are mandatory even when client-side checks exist. Authentication establishes identity, whereas authorization determines permitted actions.

Configuration should vary safely by environment, secrets should be protected, and logs should support diagnosis without exposing sensitive data. Centralized error handling creates predictable responses and prevents internal details from reaching users.

Monolithic, layered, MVC, clean, event-driven, microservice, and serverless architectures represent different trade-offs. A modular monolith may be preferable to microservices for a small team, while events or serverless functions may be appropriate for asynchronous or variable workloads. Architecture should follow domain boundaries, organizational capability, reliability needs, and operational evidence.

Key Terms

Authentication: Process of establishing a user or system identity.

Authorization: Decision about which actions an authenticated subject may perform.

Controller: Component that coordinates an incoming request and outgoing response.

Event-driven architecture: Architecture in which components communicate through published events.

Idempotence: Property whereby repeating an operation produces the same intended effect.

Layered architecture: Organization of software into responsibility-based layers.

Middleware: Component executed between request reception and final request handling.

Microservice: Independently deployable service organized around a business capability.

MVC: Model–View–Controller separation of domain/data, presentation, and coordination roles.

Observability: Ability to understand system behavior through logs, metrics, and traces.

Parameterized query: Database query whose values are bound separately from its command text.

Routing: Mapping of HTTP methods and paths to handlers.

Serverless: Execution model in which infrastructure administration is largely delegated to a platform.

Session: Server-associated state identified by a client-held session identifier.

Template engine: Software that produces a representation by combining a template with data.

Validation: Assessment of whether input satisfies type, format, semantic, and business rules.

View model: Data structure prepared specifically for presentation.

XSS: Cross-site scripting, in which injected script executes in another user’s browser.

Review Questions

Short Answer Questions

  1. What is the difference between authentication and authorization?
  2. Why is middleware order significant?
  3. Why must server-side validation be performed even when client-side validation exists?
  4. State two important security attributes for session cookies.
  5. What information should a useful structured log contain?

Long Answer Questions

  1. Explain the complete lifecycle of an HTTP request in a layered server-side application.
  2. Compare session-based and token-based authentication, including important security considerations.
  3. Explain how MVC and clean architecture organize responsibilities differently.
  4. Discuss the benefits and costs of event-driven architecture and microservices.
  5. Design an error-handling and observability strategy for a production web application.

Analytical / Application Questions

  1. A reservation system sends confirmation email before saving the reservation. Analyze the failure modes and propose a more reliable design.
  2. A small team proposes splitting a new application into twelve microservices. Evaluate the proposal using team capability, deployment, data consistency, and operational complexity.
  3. A template displays a user-provided comment as raw HTML. Identify the security risk and specify controls at the template, validation, storage, and response layers.

Multiple Choice Questions with Answers

Question 1

Which responsibility most appropriately belongs to a controller?

A. Coordinating request input, application-service invocation, and response creation

B. Storing plaintext user passwords

C. Replacing all database integrity constraints

D. Managing the operating system kernel

Correct Answer: A. Coordinating request input, application-service invocation, and response creation

Question 2

Why must authorization be enforced on the server?

A. Because hiding a user-interface button is not a reliable security control

B. Because browsers cannot display buttons

C. Because authorization applies only to database administrators

D. Because HTTPS automatically authorizes every request

Correct Answer: A. Because hiding a user-interface button is not a reliable security control

Question 3

Which cookie attribute prevents ordinary client-side scripts from reading a session cookie?

A. Secure

B. HttpOnly

C. SameSite

D. Path

Correct Answer: B. HttpOnly

Question 4

What is the primary purpose of a parameterized database query?

A. To increase screen resolution

B. To prevent all network failures

C. To separate data values from command text and reduce injection risk

D. To eliminate the need for database constraints

Correct Answer: C. To separate data values from command text and reduce injection risk

Question 5

Which architecture commonly uses published events consumed asynchronously by other components?

A. Event-driven architecture

B. Strict presentation-only architecture

C. Single-function architecture

D. Static HTML architecture

Correct Answer: A. Event-driven architecture

Question 6

A service processes the same delivery event twice but creates only one shipment. Which property does this demonstrate?

A. Inheritance

B. Idempotence

C. Encapsulation

D. Polymorphism

Correct Answer: B. Idempotence

Question 7

Which statement best describes a monolithic application?

A. It must have no internal modules

B. It is deployed as one application unit, even if internally modular

C. It always uses serverless functions

D. It cannot use a relational database

Correct Answer: B. It is deployed as one application unit, even if internally modular

Question 8

What is the safest general response practice for unexpected production errors?

A. Return stack traces and SQL statements to the client

B. Return a consistent safe error and record diagnostic details internally

C. Ignore the error and return success

D. Expose environment variables for debugging

Correct Answer: B. Return a consistent safe error and record diagnostic details internally

Question 9

Which architectural model places business rules at the center and infrastructure at the outside?

A. Clean architecture

B. Unstructured scripting

C. Static-site architecture

D. Peer-to-peer browser architecture

Correct Answer: A. Clean architecture

Question 10

Why might asynchronous notification improve the equipment-loan case?

A. It makes database constraints unnecessary

B. It allows the reservation to succeed without waiting for the email provider

C. It guarantees that networks never fail

D. It removes the need for authentication

Correct Answer: B. It allows the reservation to succeed without waiting for the email provider

Web Application Development
Chapter 6 of 15