YUHEE1984 / CatsOneday

1 stars 0 forks source link

12 - REST API Design #10

Closed TheBeege closed 1 month ago

TheBeege commented 3 months ago

Goal

To give you the knowledge of API design needed to finish the rest of Catsoneday.

Context

Earlier, you learned what an API is and how an HTTP server can act as an API. This time, we'll talk about a specific type of API: a REST API.

Other Types of APIs

Before diving into REST specifically, let's talk about some alternatives: SOAP, RPC, and GraphQL. Note that you don't need to memorize these in details. It's just useful to recognize them if someone mentions them.

SOAP

SOAP is short for Simple Object Access Protocol, and that "simple" part is an absolute lie. SOAP is strictly XML, which is quite verbose and difficult to read. It doesn't necessarily need to use HTTP, but its structure very much mimics HTTP. Here's an example request:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://example.com/weatherservice">
    <soap:Header>
        <!-- Optional authentication information can be included here -->
    </soap:Header>
    <soap:Body>
        <ws:GetWeather>
            <ws:City>New York</ws:City>
        </ws:GetWeather>
    </soap:Body>
</soap:Envelope>
<!-- (Credit: [Apidog: SOAP Tutorial: What Is SOAP Basics](https://apidog.com/articles/soap-protocol-guide-for-beginner/)) -->

It looks a lot like HTTP, right? It has a header and a body. It has a standard structure. If HTTP wasn't a popular standard, SOAP wouldn't be so bad. Long ago, HTTP wasn't necessarily a standard communication protocol between servers, so they often used SOAP. Fortunately, most organizations are happy to use HTTP for communication between services, so this complexity is handled by the protocol rather than us needing to handle it directly ourselves.

RPC

RPC is short for remote procedure call. RPC APIs are also protocol-agnostic, like SOAP, but most RPC APIs use HTTP these days. The key aspect of RPC APIs is that they call a specific function in the target application and pass parameters. This is much simpler to design, since the API endpoints directly map to the application's functions, but it's less intuitive. Users of the API must have a deeper understanding of the application to use the API effectively. An example endpoint, assuming an HTTP RPC API, might be GET /getPackages or POST /createAndShipOrder. RPC APIs are still quite popular. They're useful in cases where REST doesn't fit well, and there is still ongoing development of RPC systems. Google's gRPC library is one example.

GraphQL

GraphQL is short for graph query language. GraphQL is the newest type of API that is popular. It allows clients to dynamically request what data they want from the server and how to structure it. This can be useful for reduce the number of calls between client and server, but it creates a lot more effort for server development to support the flexibility (in my opinion). If your application has complex relationships where individual entities aren't terribly useful alone or you have far more backend engineers than frontend, GraphQL may be a good choice. It can also be useful in cases where your client is highly dynamic and will need very different structures of data for each request.

What is REST?

Now to the important part: what is REST? REST is short for Representational State Transfer. Honestly, the name is terrible. The core idea is that entities, or resources, are represented in some format like JSON or XML, and their state is transferred back and forth between client and server.

One key aspect of this is state: REST APIs are stateless. What does that mean? It means that every request and response doesn't need to know about any previous or next requests or responses. Each transaction happens in isolation. This makes our job much easier.

Another key aspect is the idea of resources. REST APIs are organized according to their resources. In our application, cats and owners are resources, so we would have /cats and /owners endpoints. REST uses HTTP's methods to describe how we interact with the resources. Let's review that below:

We also call the REST operations "CRUD." This is short for Create, Read, Update, Delete. POST mostly maps to create. GET maps to read. PUT mostly maps to update. And, surprise, DELETE is delete.

In REST, it is also possible to "nest" resources, or define resources that belong to one another in a hierarchy. A classic example is books. A book consists of chapters, and chapters cannot exist without a book. So we may have an endpoint like /books/{id}/chapters. However, we would not do this for authors, as an author can exist without a book, and a book can exist without an author. Therefore, /authors/{id}/books would be incorrect, but /authors and /books would be just fine.

But then what if you want to find all books by an author? We can constrain how we search for resources using query string parameters. You've already encountered them. They look like this: ?key=value. In this example, we would do /books?author=5 or maybe /books?author_name=Shakespeare. You can also provide multiple query string parameters to do more filtering: /books?author_name=Shakespeare&genre=comedy. Just use an ampersand & to separate each parameter.

We skipped over something important. Remember /books/{id}/chapters? The curly brackets in {id} indicate that this is a path variable. It can change. The id bit is just a name for the variable. You've also encountered this already. You'll often see IDs or "slugs" used as path variables. Slugs are generally considered more secure, as they hide away the details of your internal data structure. A slug is a unique, short name for the resource, often with some random numbers or letters added to guarantee uniqueness. As a junior, you (hopefully) won't be in charge of making a design decision like this, but it's good to know about.

Examples

Let's come up with some examples specific to our project that would make for good endpoints.

Now, your cat tamagotchi server would probably be quite simple, but that is by design. The client would handle actions like feeding the cat or petting the cat. The server would just track how the cat was changed, like changing some energy level or mood level.

Theoretically, you could design it such that actions for a cat are a resource. It would be a little awkward and arguably not REST, but since your focus is more on backend than frontend, it would be excusable. Just make sure to note that in documentation for a potential employer to read.

Steps

  1. Define a timeline.
  2. Define a plan.
  3. Design your endpoints.
  4. Write some code.
  5. Test it.

"Beege, what is this?" This is your chance to have some fun, get more practice with your skills, and turn your portfolio project into something interesting. Based on what we've talked above and what you have so far, add more endpoints. Up to now, your server can create and read cats, but it can't edit them. It also doesn't know about owners.

Now, we haven't covered how to do relationships in Spring Boot, which is a critical thing to know. I'm explicitly not telling you how to do this part. Why? A critical skill for a junior engineer is figuring out how to find learning resources and learn on their own. I will, however, tell you what it is you need to search for. You'll want to search for many-to-many relationships in Spring Boot, since you'll likely want cats to have shared owners and for owners to have multiple cats. Remember that you need a "join table" or "linking table" when doing many-to-many relationships. If you're okay using an English resource, I recommend Baeldung, which is an excellent and popular Spring Boot resource.

The last thing I want to mention before you dive in is time. Define a deadline for yourself. Define how many hours you'll spend on this and when. As you're coming up with the plan, try to guess what you can get done in the amount of time you're giving to yourself. This is an important skill when you get a job. Project managers will expect you to have at least some idea of how long certain tasks take. Your guesses will likely be wrong, but the important part is that you start tracking and trying to understand how long things take you. Your time estimates should improve over time, and this is a critical skill on the path towards becoming a senior engineer.

So good luck! The remaining issues will be a little fun stuff and a few skills that will make you more attractive to hiring manager.

YUHEE1984 commented 1 month ago

I'm going to review the closing issues first, and then I'll plan my time based on the important points you mentioned, and then we'll talk again. Thank you. :)

YUHEE1984 commented 2 days ago

Review completed