Tutorials / Build a REST API with C# and .NET · Lesson 1 of 17

On this page

    HTTP and REST Concepts

    This is the first lesson of the tutorial, and there is no code to write yet.

    Our goal: understand the conversation between a browser and a server, and the habits REST adds on top of it. Everything we build later, an API for an online bookshop, is this conversation written in code.

    Here is the route:

    1. How the web works: one request and one response.
    2. Requests and responses in detail: methods, status codes, headers and bodies.
    3. What REST is, and why it uses more than GET and POST.

    We leave out how to write the server side. That starts in lesson 15.

    How the web works, before any code

    Start with something you do every day. You open your browser, type www.somewebsite.com and press Enter. Half a second later, a page appears.

    In that half second, two computers had a short conversation. Let's slow it down.

    One request, one response You (browser) Server 1. Request: “give me the homepage” the server finds the page 2. Response: “here’s the homepage”

    Two things happened:

    1. Your browser asked for something. This is called a request.
    2. The server answered. This is called a response.

    A few words you will see all the time:

    • A server is a computer that waits for requests and answers them.
    • A client is whatever sends the request. Here it is your browser, but later it can be a mobile app or your own code.
    • HTTP is the set of rules both sides follow, so they understand each other. A set of rules like this is called a protocol.

    That is the whole pattern. Loading a page, submitting a form, liking a post, checking a bank balance: it is always request, then response.

    Servers have no memory

    Here is the part that surprises most beginners:

    The server does not remember you.

    Each time you ask for something, the server treats it as the first time it has ever heard from you. You load a page, click a link, load another page, and to the server the second request comes from a complete stranger.

    So every request has to carry everything the server needs to answer it. This behaviour has a name: statelessness. The server keeps no state (no memory of you) between requests.

    💡 Keep this in your back pocket. Later in this tutorial we build login. If the server forgets you after every request, how does it know you are logged in on the next one? That puzzle exists because of statelessness, and there is a neat answer to it. For now, just remember the problem.

    Now that you have the shape of the conversation, let's look inside a request and a response.


    Requests and responses

    The client always speaks first

    The server never starts a conversation. It only responds to something it was asked. This is true for a browser loading a page, and it will be true for the JavaScript frontend you build later, calling your own API.

    What is inside a request

    Say you are reading a blog and click a link to the post "How to Bake Sourdough Bread". Your browser turns that click into a request. Every request, simple or complicated, has four parts:

    The four parts of a request GET /blog/how-to-bake-sourdough-bread Method + path Host: www.someblog.com Accept: text/html Headers (empty: just asking to read) Body
    • Method: one word that says what you want to do, such as GET (read) or POST (send). More on these soon.
    • Path: which thing you mean. /blog/how-to-bake-sourdough-bread reads almost like English.
    • Headers: extra information about the request, written as name: value. Think of them as sticky notes on an envelope. They describe the letter without being the letter. For example: "I would like an HTML page back."
    • Body: the content you are sending, if any. A GET has no body, because you are only asking a question.

    Method, path, headers, body. That is every HTTP request there is.

    What is inside a response

    The response has the same shape, with different content:

    The three parts of a response HTTP/1.1 200 OK Status line Content-Type: text/html Content-Length: 4021 Headers <h1>How to Bake Sourdough Bread</h1> <p>Start with a good starter...</p> Body
    • Status line: a number and a short label that say whether things went well. 200 OK means "all good". We look at these numbers shortly.
    • Headers: information about the response, such as the format and size of the content.
    • Body: the actual answer. For a normal website this is HTML, the page your browser shows.

    Here is the same conversation as plain text, exactly as it travels:

    REQUEST
    GET /blog/how-to-bake-sourdough-bread HTTP/1.1
    Host: www.someblog.com
    Accept: text/html
    
    (no body, just asking)
    
    
    RESPONSE
    HTTP/1.1 200 OK
    Content-Type: text/html
    
    <html>
      <h1>How to Bake Sourdough Bread</h1>
      <p>Start with a good starter...</p>
    </html>
    

    HTTP/1.1 is just the version of the rules being used. One ask, one answer, nothing remembered afterwards.

    Sending something: the POST example

    Not everything is about reading. Sometimes you send something to the server. Say the blog has a small feedback form with a name field and a message field:

    REQUEST
    POST /feedback HTTP/1.1
    Host: www.someblog.com
    Content-Type: application/x-www-form-urlencoded
    
    name=Sam&message=Great+post%2C+thanks%21
    
    
    RESPONSE
    HTTP/1.1 200 OK
    Content-Type: text/html
    
    <html>
      <p>Thanks for your feedback, Sam!</p>
    </html>
    

    The shape is the same as before. The only difference is that this request carries a body, because you are handing the server something new. (The odd symbols in the body are just the text made safe to send: + stands for a space.)

    GET and POST: all the early web needed

    For a long time the web needed only two methods:

    • GET: "give me something to read" (a page, an image).
    • POST: "here, take something I am sending" (a form).

    Click a link and the browser sends a GET. Submit a form and it sends a POST. Even today, a plain HTML <form> only supports those two. GET to ask, POST to submit. We will see later why more methods became necessary.

    Status codes

    Every response starts with a three-digit number. You do not need to memorise them all, but you do need to know the four families, because they tell you at a glance what happened:

    The four status code families 2xx Everything is fine Success. Nobody did anything wrong. 3xx Go look somewhere else A redirect. Not really anyone’s fault. 4xx You made a mistake The problem is in the request (the client’s fault). 5xx We messed up The server broke (the server’s fault).

    Let's meet them with a story. You click a link to the sourdough post. What could happen?

    The post exists (2xx). The server hands it over.

    • 200 OK: "Here you go." The normal, happy case.
    • 201 Created: "Done, it was added." You would see this after a successful POST that creates something, such as a new comment.

    The post moved to a new address (3xx). The owner reorganised the site.

    • 301 Moved Permanently: "This post lives somewhere else now. Go there instead." Your browser follows this automatically, so you barely notice. Behind the scenes it is a second request, to the new address.

    The post does not exist (4xx). You mistyped the URL, or the post was deleted. The mistake is on your side.

    • 404 Not Found: "That post doesn't exist."
    • 401 Unauthorized: "I don't know who you are. Log in first."
    • 403 Forbidden: "I know who you are, but you are not allowed to see this."

    ⚠️ Common mix-up. It is tempting to use 400 for "not found", but 400 Bad Request means the request itself was broken (for example, garbled data the server cannot read). "The thing you asked for isn't there" is 404.

    The server itself broke (5xx). The URL is right and the post exists, but something failed inside the server, such as its database crashing.

    • 500 Internal Server Error: "Something broke on my end. It is not your fault."

    A habit worth building: on a 4xx, first check what you sent. On a 5xx, first check the server logs. That one-digit glance saves a lot of debugging time.


    What REST is

    So far we have talked about a human with a browser. But HTTP never needed a human. It is just a shared language, and a program can speak it as well as a browser can: no clicking, just code talking to code.

    That is the idea behind REST. Instead of inventing a new way for programs to talk, reuse HTTP, which every network, server and tool already understands.

    Some words you will meet here:

    • An API is a way for one program to talk to another. A REST API is one that uses HTTP in a consistent, predictable way.
    • JSON is a simple text format for data that programs read easily, for example {"id": 42, "name": "Sam"}.

    When your ASP.NET Core API talks to the JavaScript frontend later in this tutorial, it is the same conversation you just learned: method, path, headers and body going out; status, headers and body coming back. Only two things change: who is on each end, and what comes back in the body (HTML for a human, JSON for a program).

    Resources as nouns

    A resource is a thing your API manages: a user, a blog post, an order. The core idea of REST fits in one sentence:

    The URL names the thing (a noun). The HTTP method says what to do with it (the verb).

    A common beginner design does the opposite and puts the action in the URL. Compare:

    Action in the URL (avoid) REST style
    GET /getUser?id=42 GET /users/42
    POST /createUser POST /users
    POST /updateUser?id=42 PATCH /users/42
    POST /deleteUser?id=42 DELETE /users/42

    With action URLs, every new action needs a new URL, and every team invents different names. With REST, /users/42 always means "the user with id 42", and the method decides what happens. The same works for any resource: /posts/7 is "blog post 7", /orders/15 is "order 15".

    One noun, many verbs /posts/7 the noun: this one blog post GET read it PUT replace it PATCH change a part DELETE remove it

    The pattern never changes: noun in the URL, verb in the method.

    Why more than GET and POST?

    Once code manages a resource, it needs to create, read, replace, change a small part, and remove. With only GET and POST you would be back to action URLs.

    The good news: HTTP already had the verbs. PUT, PATCH and DELETE have been in the specification for a very long time. Plain browsers and HTML forms just never used them, because a plain website did not need them. REST picks them up and gives each one a clear job. Here they are, using the blog again, this time managed by an admin panel (code), not read by a visitor:

    Method In plain words Blog example
    GET "Can I see this?" Open the sourdough post and read it. Nothing changes.
    POST "Here is a new one, please add it." Publish a brand new post.
    PUT "Replace the whole thing with this." Erase the sourdough post and rewrite it completely.
    PATCH "Change just this one part." Fix one typo in the title. Everything else stays.
    DELETE "Get rid of this." Take the sourdough post down.

    So REST does not invent verbs. It reuses verbs HTTP already had.

    REST lives inside HTTP

    REST is not a separate technology next to HTTP. It is an agreed way of using what HTTP already provides:

    REST inside HTTP HTTP methods, status codes, headers, bodies REST a set of habits for how to use HTTP no new technology

    That is also why a REST API answers with the same status codes you just learned: 2xx, 3xx, 4xx and 5xx, as on any website.

    Statelessness in REST

    REST keeps HTTP's statelessness too. Every request must carry everything the server needs, because the server remembers nothing from the request before.

    Every request stands alone Client Server Request 1: log me in as Sam Response: OK, you are logged in The server now forgets everything. Request 2: get my orders + proof it is me Response: here are your orders

    💡 This is the puzzle from the start of the lesson. If the server forgets everything, how does "being logged in" work? Not because the server remembers you, but because you prove who you are again on every request. We solve that later in this tutorial, when we build login with JWT.


    Recap

    • The web is request → response, repeated endlessly, and the server has no memory between any two of them.
    • A request has a method, path, headers and body. A response has a status, headers and body.
    • The early web needed two methods: GET to ask and POST to submit.
    • Status codes come in four families: 2xx (fine), 3xx (elsewhere), 4xx (your mistake), 5xx (the server's mistake). The family tells you where to start debugging.
    • REST reuses HTTP so programs can talk to programs: the URL names a thing, the method says what to do with it.
    • REST also brings in HTTP's other methods, PUT, PATCH and DELETE, which were in the specification all along.
    • REST keeps HTTP's statelessness: every request must carry everything it needs.

    Questions to think about

    Before the next lesson, try answering these in your own words. There are no answers given here on purpose. If you can explain them out loud to a friend, you are ready to move on.

    1. What is a request and what is a response? Who sends each one?
    2. A server is stateless. What does that mean? What must every request carry because of it?
    3. A customer opens /books/99 on an online bookshop. First case: the book was deleted. Second case: the shop's database crashed. Which status code family would you expect in each case, and whose fault is it?
    4. A bookshop API has the URL POST /deleteBook?id=5. How would you write it the REST way? Which method would you use to fix one typo in the title of book 5?
    5. A client sends "log me in as Sam". Then it sends a second request, "show my orders", with nothing else. What would the server do, and why?

    Next lesson: solutions and projects, the way .NET organizes code, so you know where everything will live when we start building.

    Solution and Project Planning →