Skip to main content
One idea at a time

Follow one task request

Your frontend sends a request to create a task. Before you think about Express syntax, follow what must happen for that task to exist.

Taskboard has two separate applications. Docusaurus publishes this course as static HTML, JavaScript, and CSS. The backend runs a Node process that receives HTTP requests and talks to PostgreSQL. Reading the course does not require the backend to run.

Imagine that Maya clicks Create task inside the Acme workspace. Her browser sends JSON to a route with the workspace and project identifiers in its path.

POST /api/workspaces/acme-id/projects/project-id/tasks
Content-Type: application/json
X-CSRF-Token: session-csrf-token
Idempotency-Key: a-new-key-for-this-operation

{"title":"Fix the mobile menu"}

The identifiers above are placeholders. The application uses UUIDs.

The API first reads the request. It checks Maya's session, verifies that she belongs to Acme, and validates the input. It also checks that the project belongs to that workspace. A valid project identifier alone does not grant access.

Next, the API writes the task and its activity record in a database transaction. PostgreSQL checks its constraints before committing the write. Only after a successful commit can the server report success.

The response contains the saved task. Your frontend can use that response to replace an optimistic placeholder with the actual identifier and version. A later lesson explains why the server also records the operation's idempotency key.

A response describes an outcome​

fetch() resolving means that the browser received an HTTP response. It does not mean that the application accepted the request. A permission failure also produces a response, so the frontend must inspect its status.

A lost response is harder. The database might have committed even though the browser reports a network error. That uncertainty explains why retries need explicit design.

The server is responsible for the durable outcome. The browser is responsible for presenting what it knows, including uncertainty when the connection fails.

Does a network error prove that the task was not created?

No. The connection can fail after PostgreSQL commits. The client needs a safe retry mechanism or a later read to learn the outcome.

Remember the sequence: identify the caller, authorize the workspace, validate the operation, commit the data, and return its result.

Read api/src/app.ts Read api/src/tasks.ts