Web Development

Chapter 7
Server-Side Development and Application Architecture

Bachelors Program in Computer Applications
Web Development   •   Bachelor

Server-Side Development and Application Architecture

Introduction

A web application is more than a collection of browser pages. The browser provides the client-side interface, while the server receives requests, applies business rules, accesses data and returns an appropriate response. Server-side development therefore connects user interaction with persistent information, security controls and organizational processes.

A typical request passes through several stages: a client constructs an HTTP request; a web server or reverse proxy accepts it; application code identifies a route; middleware performs cross-cutting tasks; a controller or handler executes application logic; data may be read or written; and a response is generated as HTML, JSON, a file or an error message. Effective server development requires both implementation skill and architectural judgment.

This chapter uses concepts applicable to frameworks such as Express, Django, Laravel, Spring Boot and ASP.NET Core. The code examples use JavaScript-like pseudocode so that the underlying ideas remain transferable.

Learning Objectives

After studying this chapter, you should be able to:

  1. Explain the request–response lifecycle and construct routes and middleware.
  2. Use templating, validation, sessions and file-handling techniques safely.
  3. Compare MVC, layered, event-driven, serverless and microservice architectures.
  4. Select and apply suitable design patterns for server applications.
  5. Evaluate reliability, security, maintainability and scalability trade-offs.

1. The Server-Side Request–Response Model

HTTP is stateless: each request is logically independent unless the application adds a mechanism for preserving state. A request generally contains a method, target URL, headers and, where appropriate, a body. Common methods include GET for retrieval, POST for creation or an operation, PUT or PATCH for modification, and DELETE for removal.

The response contains a status code, headers and an optional body. Status codes communicate broad outcomes: 2xx indicates success, 3xx redirection, 4xx a client-side problem and 5xx a server-side failure. The application should choose status codes consistently. For example, a successful form submission may return 303 See Other and redirect to a confirmation page, while an invalid request may return 400 Bad Request or 422 Unprocessable Content.

Server-side request response lifecycle ClientHTTP request Web serverproxy / TLS Applicationroute + middleware Data servicesdatabase / files HTTP response: status, headers and representation
Server-side request response lifecycle
Figure: Server-side request response lifecycle

Figure: A simplified server-side request–response lifecycle.

A server should not trust data merely because it arrived through its own interface. URLs, headers, cookies, form fields, JSON bodies and uploaded files are all external input. Authentication identifies a user; authorization determines whether that user may perform a particular action. These are different decisions and must not be conflated.

2. Routing and Controllers

Routing maps an HTTP method and URL pattern to application behavior. A route should express a resource-oriented operation clearly:

app.get('/products/:id', productController.show);
app.post('/products', requireAuth, validateProduct, productController.create);
app.patch('/products/:id', requireAuth, validateProduct, productController.update);

The parameter :id is route data, whereas a query such as /products?category=books is used for filtering or options. Route handlers should remain small. They coordinate the request and response, delegating business rules to services and persistence to repositories. This separation improves testing and prevents controllers from becoming difficult-to-maintain “god objects.”

A useful controller sequence is:

  1. Read trusted, normalized request data.
  2. Invoke an application service.
  3. Translate the result into an HTTP response.
  4. Pass unexpected errors to centralized error handling.

A route that returns a resource after creation should normally communicate the result with an appropriate status, such as 201 Created, and may include a Location header. It should not expose database stack traces or internal credentials in error responses.

3. Middleware and Cross-Cutting Concerns

Middleware is a function positioned in the request pipeline. It may inspect or modify a request, produce a response, or call the next middleware. Typical uses include logging, parsing, authentication, rate limiting, input normalization, security headers and error handling.

app.use(requestLogger);
app.use(parseJson({ limit: '1mb' }));
app.use(securityHeaders);
app.use('/admin', requireAuth, requireRole('admin'), adminRoutes);
app.use(errorHandler);

Order matters. A parser must run before code reads the parsed body; authentication must precede protected routes; and the error handler must be able to receive errors from earlier components. Middleware should have one clear responsibility and should not silently swallow failures.

A production error handler should log a correlation identifier, record diagnostic details in a protected logging system and return a stable public message. Logging must avoid passwords, session identifiers, access tokens and unnecessary personal data. Correlation identifiers help connect a client-visible failure with server logs without revealing internal information to the client.

4. Server-Side Templating

A template combines a presentation structure with server-provided data to produce HTML. The controller supplies a view model; the template renders it. This is distinct from inserting arbitrary strings into HTML.

return res.render('orders/show', {
  order: order,
  canCancel: currentUser.id === order.customerId
});

The most important templating security rule is context-aware output encoding. Text inserted into HTML body content requires HTML escaping; content inserted into a JavaScript, URL or CSS context requires the corresponding protection. A template engine’s automatic escaping should be enabled, and raw or “safe HTML” output should be rare, reviewed and sanitized.

Templates should avoid database queries and complex business rules. Reusable layouts, partials and components reduce duplication. For large applications, server-rendered HTML may be combined with client-side enhancement, but the server remains responsible for authorization and validation.

5. Validation and Data Integrity

Validation is the systematic checking of input against defined constraints. It has at least three levels:

LevelPurposeExample
SyntacticChecks form and typeEmail has an acceptable structure
SemanticChecks meaningEnd date is not before start date
BusinessChecks policyA customer may not exceed a credit limit

Client-side validation improves usability but is not a security boundary. The server must validate again because clients can be modified or bypassed. Validation should normalize data where appropriate, reject unexpected fields and apply limits to length, quantity and nested structure.

Validation does not replace parameterized database queries. If a user supplies an identifier, the application should validate its format and still use a parameterized query. A safe conceptual example is:

const row = await db.query(
  'SELECT * FROM users WHERE id = ?',
  [validatedId]
);

The database should also enforce invariants such as uniqueness, referential integrity and non-null requirements. Application validation provides prompt feedback; database constraints protect integrity when multiple processes or tools write to the same data store.

6. Sessions, Cookies and Authentication

HTTP does not remember prior requests. A session system supplies continuity by associating a client-held cookie with server-managed state, or by using a signed or encrypted token. A secure session cookie commonly uses:

  • Secure, so it is sent only over HTTPS;
  • HttpOnly, so ordinary client-side scripts cannot read it;
  • an appropriate SameSite policy to reduce cross-site request risks;
  • a limited expiration period and rotation after authentication.

Session identifiers must be unpredictable. Passwords must never be stored in plaintext; they should be processed with a deliberately slow, adaptive password-hashing algorithm such as Argon2id, bcrypt or scrypt, with a unique salt. Encryption is not a substitute for password hashing.

Session-based authentication is often convenient for browser applications. Stateful sessions require a shared or distributed session store when multiple application instances are used. Stateless tokens can reduce server-side session storage but introduce difficult revocation, rotation and leakage concerns. The choice depends on threat model and operational requirements rather than fashion.

Cross-site request forgery (CSRF) is relevant when browsers automatically attach credentials, especially cookies. Common defenses include anti-CSRF tokens, suitable SameSite settings and origin checking. Authorization checks must occur on every protected operation; hiding a button is not authorization.

7. Secure File Handling

File uploads combine untrusted metadata, large input and potentially dangerous content. A robust process should:

  1. Authenticate and authorize the upload operation.
  2. Enforce request-size, file-count and storage quotas.
  3. Validate the declared type and inspect file content where feasible.
  4. Generate a server-side filename rather than trusting the original name.
  5. Store uploads outside executable public directories where possible.
  6. Apply least-privilege permissions and malware scanning appropriate to risk.
  7. Serve downloads through authorization-aware handlers.
  8. Record ownership, size, type and retention information.

Never construct a filesystem path directly from an untrusted filename. Path traversal sequences such as ../ must not influence storage location. A safe design maps an opaque identifier to metadata in a database and keeps the physical path private. Public content delivery may use an object-storage service with short-lived signed URLs, but the authorization decision should still be made by the application.

8. Architectural Models

Architecture describes the major responsibilities, boundaries and communication relationships of an application. No architecture is universally superior; selection depends on domain complexity, team structure, deployment constraints, performance and organizational capacity.

8.1 MVC Architecture

Model–View–Controller separates domain or data concerns, presentation and request coordination. A request reaches a controller, which obtains or changes model data and selects a view. MVC encourages separation of concerns and is effective for server-rendered applications. However, poorly designed systems may place all business rules in controllers or create models that are merely database wrappers.

8.2 Layered Architecture

A common layered structure is presentation, application/service, domain and infrastructure/data access. Dependencies generally point inward or toward stable abstractions. The model supports substitution and testing, but excessive layers can create ceremony and slow simple changes.

8.3 Event-Driven Architecture

In an event-driven system, a producer publishes an event such as OrderPlaced; interested consumers react independently. This reduces direct coupling and supports asynchronous work such as email or analytics. It introduces eventual consistency, duplicate delivery, ordering and observability challenges. Consumers should be idempotent: processing the same event more than once should not produce an incorrect repeated effect.

8.4 Serverless Architecture

Serverless applications run functions or managed services under a provider’s operational model. They can scale automatically and reduce infrastructure administration. Limitations include cold starts, execution limits, provider coupling, distributed debugging and variable cost. Serverless does not eliminate architecture; data ownership, authorization, retries and monitoring remain application responsibilities.

8.5 Microservices

Microservices divide a system into independently deployable services organized around business capabilities. Benefits may include team autonomy, independent scaling and technology flexibility. Costs include network failure, data consistency problems, deployment complexity, distributed tracing and operational overhead. A modular monolith is often a more appropriate starting point when a team lacks a strong reason to distribute.

ArchitectureMain strengthMain riskSuitable context
MVCClear web interaction separationBloated controllers/modelsServer-rendered applications
LayeredMaintainability and testabilityExcessive indirectionMost business applications
Event-drivenLoose coupling and asynchronous workEventual consistencyNotifications, workflows, integration
ServerlessManaged scaling and infrastructureLimits and provider dependenceVariable workloads and managed services
MicroservicesIndependent deployment by capabilityDistributed-system complexityLarge products and autonomous teams

9. Design Patterns for Server Applications

Design patterns are reusable solutions to recurring design problems, not mandatory code templates.

  • Repository: abstracts persistence operations, allowing services to depend on a domain-oriented interface.
  • Service layer: coordinates use cases and transactions without embedding them in controllers.
  • Dependency injection: supplies dependencies from outside a component, improving substitution and testing.
  • Adapter: translates one interface into another, useful for payment, storage or messaging providers.
  • Strategy: selects interchangeable algorithms, such as shipping or pricing policies.
  • Factory: centralizes creation when object construction depends on configuration or type.
  • Observer or publish–subscribe: notifies interested components, often through events.
  • Unit of work: groups changes and commits them as a coordinated transaction where the data technology supports it.

Patterns can be harmful when applied mechanically. For example, a repository that merely duplicates every ORM method may add complexity without improving a boundary. The design should be justified by change, testing or domain clarity.

10. Worked Application: Campus Equipment-Rental Service

The following is an illustrative case. A university wants students to reserve cameras and laboratory equipment through a web application.

Background and problem

The first prototype stores reservation logic in route handlers. It accepts a student ID from a form, writes uploaded identity documents using the original filename and sends confirmation email during the request. Under concurrent use, two students can reserve the same item. Error messages expose database details, and administrators cannot audit changes reliably.

Analysis

The system has several boundaries: identity and authorization, reservation policy, inventory persistence, document storage and notification. The immediate problem is not simply choosing microservices; it is separating responsibilities and protecting invariants. The rule “an item cannot have overlapping approved reservations” must be enforced consistently even when requests arrive nearly simultaneously.

Approach

A modular layered monolith is selected initially:

  • Routes/controllers: translate HTTP requests and responses.
  • Authentication middleware: identifies the student and administrator.
  • Reservation service: checks eligibility, dates and availability.
  • Repository: performs parameterized data operations.
  • File service: stores documents under generated identifiers outside the public web root.
  • Event publisher: records ReservationApproved after a successful transaction.
  • Notification consumer: sends email asynchronously and retries safely.

The service validates dates and item identifiers, while the database supplies a transaction and a constraint appropriate to its capabilities. The application returns a generic error to the user and logs a correlation ID. An administrator can later inspect an audit record containing actor, action, time and affected reservation.

Outcome

The request path becomes shorter because email is asynchronous. The modular boundaries permit later extraction of notification or document storage if scale justifies it. The system remains operationally simpler than an immediate microservice deployment.

Learning points

  1. Architecture should respond to actual constraints rather than trend-driven complexity.
  2. Security controls must be applied at the server boundary and storage boundary.
  3. Business invariants require durable enforcement, not only interface checks.
  4. Asynchronous events are useful when delayed completion is acceptable.
  5. Modularity is valuable even when deployment remains a single application.

11. Reliability, Performance and Operations

Production architecture includes operational behavior. Timeouts prevent a slow dependency from consuming all request resources. Retries should be limited, use backoff where appropriate and avoid repeating non-idempotent operations without an idempotency key. Circuit breakers can temporarily stop calls to an failing dependency, allowing recovery and protecting the caller.

Caching can reduce latency and load, but cached authorization-sensitive data requires careful invalidation. Database connection pools should be bounded. Large files and long-running tasks should normally use streaming or background workers rather than occupying a request indefinitely.

Observability combines logs, metrics and traces. Useful indicators include request rate, error rate, latency distribution and resource saturation. A single average latency can conceal severe tail latency; therefore percentiles such as p95 or p99 are often more informative. Observability data itself may contain personal or confidential information and requires access control and retention policies.

12. Ethical, Legal and Governance Considerations

Server applications process personal information, so collection should be limited to a legitimate purpose. Organizations should define retention, deletion and access procedures, protect data in transit and at rest, and document processing responsibilities as required by applicable law. Accessibility should be considered in server-rendered forms and error responses, not treated only as a visual-design concern.

Developers must consider algorithmic bias when server logic makes decisions about eligibility, ranking or access. Automated decisions should be explainable at an appropriate level, reviewable and monitored for discriminatory outcomes. AI-generated code must undergo human review for security, licensing, privacy and correctness; generated code is not automatically trustworthy.

13. Contemporary Development Practices

Containers and infrastructure automation make environments reproducible, but they do not remove the need for secure configuration and patch management. Continuous integration should run unit, integration and security tests. Secrets belong in a secret-management system rather than source control. Software supply-chain controls include dependency review, lockfiles, vulnerability monitoring and provenance where available.

API design increasingly includes JSON APIs, webhooks and asynchronous messaging. Contract testing helps ensure that independent components agree on schemas. OpenAPI-like specifications can document endpoints, authentication and error formats. Regardless of technology, stable contracts, backward compatibility and meaningful deprecation policies reduce integration failures.

Best Practices Checklist

  • Keep controllers thin and business rules in testable services.
  • Validate and normalize every external input on the server.
  • Use parameterized database operations and database constraints.
  • Encode template output according to its context.
  • Protect cookies, sessions, passwords and uploaded files.
  • Separate authentication from authorization.
  • Use centralized, privacy-aware error handling and observability.
  • Prefer asynchronous processing for slow, retryable work.
  • Choose a modular monolith before microservices unless distribution is justified.
  • Document architectural decisions and revisit them as evidence changes.

Chapter Summary

Server-side development implements the request–response lifecycle through routing, middleware, controllers, services, persistence and response generation. Routing identifies operations, while middleware handles cross-cutting concerns such as authentication, parsing, logging and security. Templates must escape output correctly; validation must occur on the server; sessions and cookies require secure configuration; and file uploads demand strict authorization, type, size and storage controls.

MVC and layered architectures provide separation of responsibilities. Event-driven designs support loose coupling and asynchronous work but introduce eventual consistency. Serverless platforms reduce infrastructure administration while imposing execution and provider constraints. Microservices can support independent deployment but create substantial distributed-system complexity. Patterns such as repositories, service layers, dependency injection, adapters and strategies are useful when they clarify genuine boundaries.

A sound architecture balances functionality, security, maintainability, performance, reliability and organizational capability. Modular design, observable operations, privacy-aware governance and evidence-based technology choices are more important than adopting a fashionable architecture.

Key Terms

Authentication: Verification of a user or system identity.

Authorization: Determination of what an authenticated identity may do.

Controller: Component that coordinates an HTTP request and response.

CSRF: An attack causing a browser to submit an unwanted authenticated request.

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

Idempotency: Property whereby repeating an operation does not create an incorrect additional effect.

Layered architecture: Organization into responsibility-based layers with controlled dependencies.

Middleware: Request-pipeline component that performs processing before or after a handler.

Microservice: Independently deployable service organized around a business capability.

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

Parameterized query: Database operation that separates command structure from supplied values.

Repository: Abstraction for accessing persisted domain data.

Route: Mapping between an HTTP method/path and application behavior.

Serverless: Provider-managed execution model in which application functions run without direct server administration.

Session: Mechanism for preserving authenticated or application state across requests.

Template: Presentation structure populated with server-side data.

Validation: Checking that input satisfies syntactic, semantic and business constraints.

View model: Data prepared specifically for presentation by a view or template.

Review Questions

Short Answer Questions

  1. What is the difference between authentication and authorization?
  2. Why does middleware order matter?
  3. State two secure attributes commonly applied to session cookies.
  4. Why must server-side validation be performed even when client-side validation exists?
  5. What is the purpose of a repository pattern?

Long Answer Questions

  1. Explain the server-side request–response lifecycle, including the roles of routing, middleware, controllers and services.
  2. Compare MVC and layered architecture, including their benefits and possible weaknesses.
  3. Describe a secure design for handling uploaded files.
  4. Explain the advantages and operational challenges of event-driven architecture.
  5. Discuss why a modular monolith may be preferable to immediate microservice adoption.

Analytical / Application Questions

  1. A web application sends email synchronously while processing every order. Analyze the likely reliability and performance problems and propose an improved design.
  2. Design the validation, authorization and storage flow for an administrator uploading confidential student documents.
  3. A reservation system permits duplicate bookings during periods of high traffic. Identify which application and database mechanisms should be examined and propose a corrective architecture.

Multiple Choice Questions with Answers

Question 1

Which responsibility is most appropriate for middleware?

A. Rendering every database table directly

B. Handling cross-cutting concerns such as authentication and logging

C. Replacing all database constraints

D. Storing passwords in plaintext

Correct Answer: B. Handling cross-cutting concerns such as authentication and logging

Question 2

Why must server-side validation be performed when client-side validation already exists?

A. Clients cannot be modified by users

B. Server validation improves page colors

C. Client checks can be bypassed or altered

D. It eliminates the need for authorization

Correct Answer: C. Client checks can be bypassed or altered

Question 3

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

A. HttpOnly

B. Public

C. Indexed

D. Mutable

Correct Answer: A. HttpOnly

Question 4

What is a principal benefit of parameterized database queries?

A. They guarantee zero network latency

B. They separate query structure from supplied values

C. They automatically authorize every user

D. They remove the need for database backups

Correct Answer: B. They separate query structure from supplied values

Question 5

Which architecture communicates primarily through published events?

A. Event-driven architecture

B. Pure MVC architecture

C. Single-table architecture

D. Static-page architecture

Correct Answer: A. Event-driven architecture

Question 6

What is the safest general approach to an uploaded filename?

A. Use it directly as a filesystem path

B. Append it to a public directory without checking

C. Replace it with a server-generated identifier

D. Execute it to detect its type

Correct Answer: C. Replace it with a server-generated identifier

Question 7

Which statement best describes authorization?

A. Verifying a password-hashing algorithm

B. Determining what an identity is permitted to do

C. Compressing an HTTP response

D. Converting a template into HTML

Correct Answer: B. Determining what an identity is permitted to do

Question 8

Why can microservices increase operational complexity?

A. They eliminate network communication

B. They create distributed concerns such as tracing and network failure

C. They prevent independent deployment

D. They require every application to use one database table

Correct Answer: B. They create distributed concerns such as tracing and network failure

Question 9

Which design pattern supplies dependencies from outside a component?

A. Dependency injection

B. Observer

C. Factory reset

D. Template inheritance

Correct Answer: A. Dependency injection

Question 10

Which is an appropriate reason to process notification email asynchronously?

A. Email never fails

B. It can reduce request latency and isolate retryable work

C. It removes the need for authentication

D. It guarantees messages arrive instantly

Correct Answer: B. It can reduce request latency and isolate retryable work

Web Development
Chapter 7 of 15