Oppitunti 1/159

Tarkistetaan oppitunnin käyttöoikeutta...

Video ja kirjallinen oppitunti · 7 min

Welcome to the Engineering Team

The team, the project, the role of a backend engineer, and why behaviour comes before code.

EsikatseluTekstitysPian

Katselet ilmaista esikatseluoppituntia.

In this course, we are not going to learn Java or Spring Boot features through a collection of isolated examples. Instead, we will build a real-world backend application and evolve that same application throughout the course.

You are not just a learner here. From this moment on, imagine that you have joined a software engineering team as a new Backend Engineer. Your team is about to build a new Order Management Backend.

The system will allow customers to browse products, place orders, make payments, view their order history and cancel eligible orders. Administrative users will be able to create and update products, deactivate products, manage inventory and view orders.

But we are not going to start by writing code. Professional software development usually does not begin with "new project, open the IDE, start coding". A more realistic process looks like this:

Piirretään kaaviota…

The purpose of this course is to let you experience that entire process in practice.

The Project We Are Joining

Imagine that we work for a commerce company. The company already sells products, but now it wants a dedicated backend system for its ordering process, and our team's responsibility is to build that backend.

The initial version will support several core capabilities:

  • product management
  • inventory management
  • order creation
  • payment processing
  • order history
  • order cancellation
  • administrative operations

Customer identity will come from the application's authentication mechanism. We are not building a separate customer-account management subsystem as part of this project.

As the course progresses, we will implement these capabilities gradually. Keep one important idea in mind:

We are not going to build the entire system at once.

Professional software is usually delivered through small, reviewable, incremental changes. Our project will evolve the same way.

Your Role

In this project, you are a Backend Engineer. That means your job is not limited to writing APIs. A backend engineer may need to:

  • understand product requirements
  • identify ambiguous requirements and ask clarifying questions
  • design technical solutions
  • define API contracts
  • design database models
  • implement business logic
  • write tests
  • review another engineer's code
  • explain technical changes
  • investigate production failures
  • modify an existing system safely
  • document technical decisions

Throughout the course, we will practise different parts of these responsibilities.

Software Development Is More Than Writing Code

When learning programming, we often work with a simplified model: a problem goes in, we write code, and the code produces output. That model is useful for small programming exercises. Production software is different: there are many important decisions between the problem and the code.

Suppose a Product Manager says:

A customer should be able to place an order.

That sounds simple. But as backend engineers, we should immediately start asking questions:

  • Can an order contain multiple products? Can the same product appear more than once?
  • What happens if inventory is insufficient? When should inventory decrease?
  • Can a customer cancel an order? Can an unpaid order be cancelled? Can a paid one?
  • What happens if payment succeeds but our database update fails?
  • How do we calculate the final price? Should it come from the current product price, and what happens if that price changes later?

This is one of the major differences between software engineering and simply writing code. Writing the code is often the most straightforward part. The difficult part is:

Understanding exactly which problem needs to be solved and how the system should behave.

We Will Not Start With Spring Boot

This is a Java backend development course. Even so, the first few lessons will contain very little Spring Boot code, and that is intentional.

A framework is a tool. Spring Boot gives us capabilities such as HTTP controllers, dependency injection, configuration, database integration, validation and application lifecycle management. But Spring Boot cannot decide whether:

  • the requirement has been understood correctly
  • a responsibility belongs in the right component
  • an API contract is well designed
  • a business invariant has been identified
  • a transaction is required
  • a failure scenario has been handled correctly
  • a change is risky
  • a production incident has been investigated properly

Learning the framework is important, but knowing a framework and being a backend engineer are not the same thing. Throughout this course, we will develop both: backend engineering thinking and its implementation in Java and Spring Boot.

Our Engineering Workflow

Throughout the course, we will follow a repeatable engineering workflow. A feature will usually move through a process similar to this:

Piirretään kaaviota…

Not every small change needs a full RFC. That is also an important engineering lesson: documentation should not exist to create bureaucracy. Its purpose is to improve thinking and communication where those things are valuable. Later, we will learn when a short engineering ticket is enough, when an ADR is appropriate and when a larger RFC is worth writing.

RFCs and ADRs

You will see the term RFC throughout this course. RFC commonly stands for Request for Comments. In a software engineering team, an RFC can be a document in which an engineer explains a technical problem and proposes a solution so that other engineers can review it before implementation. An RFC might contain sections such as Problem, Context, Goals, Non-Goals, Proposed Design, Alternatives, Risks and Rollout Plan.

Not every company uses the same format. Some teams call these documents design documents, technical proposals or engineering proposals. The name is less important than the purpose:

Think about and discuss important technical decisions in a structured way before hiding those decisions inside code.

We will write RFCs for our Order Management Backend when the problem justifies one.

Another term we will use is ADR — Architecture Decision Record. An ADR records a specific technical decision and the reasoning behind it, for example why we are using PostgreSQL, why we are using database migrations or why we chose a particular API error format.

An RFC may describe a larger technical proposal; an ADR usually focuses on preserving one important decision and its reasoning. Months later, when another engineer joins the project, they should not have to reverse-engineer the reason behind every architectural choice by reading code. They should be able to read the relevant ADR and understand the context.

Engineering Tickets

After designing a solution, we will break the work into smaller engineering tasks:

text
BACKEND-101 Bootstrap Order Management Backend
BACKEND-102 Configure PostgreSQL and Flyway
BACKEND-103 Model the Product Domain
BACKEND-104 Persist Products
BACKEND-105 Implement Product Administration

A useful ticket should not simply say "Build orders" or "Implement ordering system": with a scope that large, an engineer may not even know where to start. A well-written ticket creates a useful boundary around engineering work. Compare it with:

markdown
BACKEND-112 Implement Order Creation Workflow

Create an order for an authenticated customer.

Acceptance Criteria:

- Order must contain at least one item.
- Every referenced product must exist.
- Requested quantity must be available.
- Order total must be calculated from server-side product prices.
- Invalid requests must return an appropriate API error.

The problem is now much clearer. Smaller engineering work is easier to review, test, roll back and parallelize, and it keeps risk small.

Pull Requests Are Communication

Writing the code does not mean the work is finished. In a professional engineering team, a change usually goes through review: we create a Pull Request, commonly called a PR. A useful PR description might look like this:

markdown
## What

Adds order cancellation support.

## Why

Customers need to cancel unpaid orders.

## Changes

- Added cancellation domain logic
- Restores consumed inventory
- Added cancellation API
- Added integration tests

## Testing

- Unit tests
- API integration tests

## Risks

Inventory restoration happens inside the order transaction.

A PR is not just a container for code. It is communication with the reviewer, who should be able to understand quickly what changed, why it changed, how it was tested and where the risks are. This is an extremely important skill in a real engineering career.

Production Changes Everything

Running an application successfully on a local machine is not the end of software development. Production systems introduce additional questions:

  • How will we know if the service is healthy?
  • What happens when the database is unavailable, or when an external payment API times out?
  • How do we find a failed request?
  • What happens during deployment? Can a database migration break existing application instances?
  • Can the same payment request be processed twice?
  • What happens if two customers try to buy the final item simultaneously?

Questions like these are what make backend engineering interesting. We do not need to know every answer at the beginning of the course. In fact, we should not try to solve every possible future problem immediately. As the system evolves, new problems will naturally appear, and then we will learn and apply the appropriate solution.

We Will Make Mistakes

We will not begin the course with a perfectly designed system, and real software rarely begins with perfect architecture either. We will make decisions. Later, new requirements will arrive, some assumptions may turn out to be wrong and some designs may need to change. We will even simulate a production incident.

That is not a failure of the course. That is software development: real systems evolve over time. A strong engineer's skill is not simply the ability to write the correct code on the first attempt. It is also:

The ability to change an existing system safely.

Our First Version Will Be a Modular Application

Our Order Management Backend will begin as a single backend application. Conceptually:

text
Order Management Backend
├── Products
├── Inventory
├── Orders
└── Payments

Customer identity is supplied by the authentication system and used by application workflows, but we are not creating a separate Customer management capability.

We will not split it into microservices or add infrastructure such as Kafka or distributed caches before a real problem requires them; module 2 makes that decision explicitly. A system that satisfies its requirements with a simpler architecture is usually a better starting point.

What We Will Build Toward

By the end of the course, our application will be much more than a collection of CRUD endpoints. We will build a backend with HTTP APIs, business logic, domain models, validation, PostgreSQL persistence, database migrations, transactions, authentication and authorization, external service integration, tests, logging, metrics, health checks, Docker, CI and deployment practices.

But we will not learn these as an arbitrary checklist. Each capability will appear because the project creates a reason for it:

  • We will learn PostgreSQL because the application needs durable data.
  • We will learn transactions because Order creation changes multiple pieces of database state that must remain atomic.
  • We will learn authentication and authorization because one Customer must not be able to access another Customer's Orders.
  • We will learn timeouts and retries because an external payment provider will not always respond perfectly.
  • We will learn observability because when something fails in production, engineers need to understand what happened inside the system.

This distinction is important:

Problem first. Technology second.

Your Engineering Repository

As the course progresses, our repository may evolve into something like:

text
order-management/
├── src/
│   ├── main/
│   └── test/
├── docs/
│   ├── rfcs/
│   ├── adr/
│   └── incidents/
├── Dockerfile
├── compose.yaml
└── README.md

src/ contains application code, docs/rfcs/ larger technical proposals, docs/adr/ architecture decisions, and docs/incidents/ will later contain production incident reviews. Engineering context becomes part of the repository alongside the code.

A Backend Engineer Thinks in Behaviour

The questions we asked about "place an order" point to one habit we will practise throughout the course: when a feature request arrives, think about behaviour before implementation. "Customer can cancel an order" is not order.setStatus(OrderStatus.CANCELLED);. It raises questions first: which orders can be cancelled, whether inventory is restored, whether the same order can be cancelled twice, who may cancel it and what the API returns. Behaviour first, then design, then code.

Think Like You Just Joined the Team

At this point, all we know is the high-level context: the company wants an Order Management Backend. An inexperienced developer might already open an IDE and create an OrderController. We are not going to do that. Our next responsibility is to understand the business requirement: who will use the system, what they should be able to do, which behaviours are mandatory or out of scope, which constraints exist and how success will be defined. Without that information, we might write code quickly and still build the wrong system.

Practice Exercise 1: Questions Before Code

Solutions: lesson 1.09.

Module 1 produces documents, not code, so start a workspace for them now: a folder of your own, for example backend-course/, with a docs/ folder inside. The order-management repository itself starts in module 3.

The Product Manager adds one sentence: "Administrators should be able to deactivate a product." Create docs/questions-deactivate-product.md and write at least six questions you would want answered before anyone writes product.deactivate(). Cover who may do it, what happens to Customers browsing and ordering, what happens to existing Orders, whether it can be undone, and what happens if it is done twice. Do not answer them; this lesson is about noticing them.

Practice Exercise 2: Which Document?

For each piece of information, choose where it belongs: a ticket, a Pull Request description, an RFC in docs/rfcs/, an ADR in docs/adr/ or an incident review in docs/incidents/. Give one reason for each.

  1. Why the team chose PostgreSQL over other databases.
  2. A proposal for how the backend will call the Payment provider, with alternatives, risks and a rollout plan, for the team to review before anyone implements it.
  3. "Reject Order items with a quantity below 1."
  4. What this change does, how it was tested and what a reviewer should look at closely.
  5. What happened last Tuesday when Payments failed for 40 minutes, and what the team will change.

Practice Exercise 3: Review a Pull Request Description

A teammate opens a Pull Request with this description. Find what a reviewer cannot learn from it, using the What / Why / Changes / Testing / Risks shape from this lesson.

markdown
## What

Cancellation.

## Changes

- Updated some files
- Fixed stuff in Inventory

## Testing

Works on my machine.

Knowledge Check

Question 1

Why does this course spend its first lessons on requirements instead of Spring Boot code?

Question 2

"Build orders" names something everyone on the team understands. Why is it still a poor ticket?

Question 3

Both an RFC and an ADR record technical thinking. What does each one keep, and what does a new engineer lose months later if neither exists?

Question 4

Why does a useful Pull Request description have a Risks section, even when the change is small?

Question 5

A teammate suggests starting with microservices and Kafka "because we will need them eventually". What does "problem first, technology second" answer?

Knowledge Check Answers

Answer 1

Spring Boot can implement a behaviour, but it cannot tell us which behaviour is correct. If the requirement is misunderstood, well-written code still builds the wrong system, so understanding comes first.

Answer 2

Its scope is so large that an engineer does not know where to start, a reviewer cannot judge it and nobody can tell when it is finished. A good ticket puts a boundary around one reviewable, testable piece of work.

Answer 3

An RFC proposes a larger design for review before implementation; an ADR preserves one decision and why it was made. Without them, a new engineer has to reverse-engineer the reasons from code, and may undo a decision whose reason is invisible.

Answer 4

The reviewer's attention is limited, and the author knows best where the change could go wrong, for example that Inventory restoration runs inside the Order transaction. Naming the risk points the review at it; "no special risk" is also useful information.

Answer 5

Technology should appear because the project creates a reason for it. No current requirement needs separate services or a message broker, and a simpler architecture that satisfies the requirements is a better start; module 2 makes that decision explicitly.

Engineering Principle

The job is not to write code. The job is to solve the right problem with software.

Code is an important part of that job. But before code comes understanding, and after production comes ownership. A backend engineer participates in the entire lifecycle.

Summary

  • We join a team building the Order Management Backend and evolve that one application through the whole course.
  • A backend engineer's work goes from understanding requirements and asking questions through design, implementation, testing and review to operating the system in production.
  • Spring Boot is a tool; it cannot decide whether we understood the requirement or designed the behaviour correctly.
  • RFCs propose larger technical changes for review; ADRs preserve one decision and its reasoning; tickets give work a clear, reviewable boundary.
  • A pull request is communication: what changed, why, how it was tested and where the risks are.
  • We start with a simple modular application and add technology only when a real problem requires it: problem first, technology second.
  • Behaviour comes before design, and design before code.

In the next lesson, our team receives the actual product requirement for the Order Management Backend. It intentionally begins at a high level, and we will read it like engineers: separating what is explicitly required from what we are assuming, what is ambiguous, what needs clarification and what should not be built yet.

Mieti ensin

Tulossa pian

Välikysymyksiä, joissa valitset vastauksen ennen kuin oppitunti näyttää sen.