DEV Community

Sharad Raj (He/Him)
Sharad Raj (He/Him)

Posted on

How will you structure REST APIs as an experienced engineer ?

I'm asking about the way you divide the code and the patterns that you use.

Latest comments (9)

Collapse
 
cgcnu profile image
sreenivas

I will read up on everything and anything written by twitter.com/philsturgeon He has tons of resources on API design

Collapse
 
loujaybee profile image
Lou (🚀 Open Up The Cloud ☁️) • Edited

Great question. Answering this in a single comment is hard.

First, a few guiding thoughts:

  • There's no one pattern that solves everything
  • Sometimes you can over-engineer and add unnecessary abstractions
  • The best thing to do is to build, and refactor

Build something, refactor, build, refactor. Over time, you'll gain a sixth sense for where problem areas are emerging and where you might need to refactor or reach into your toolbox of patterns in order to help tidy something up. Don't beat yourself off for starting simple, if one file returns the stuff you need, it works, there's no shame in that.

Two big tips:

  1. Write integration tests — When you have a good set of integration tests, which test your contract from the outside-in you're going to have great confidence to refactor your code underneath. This is the biggest tip I can give you.

  2. Use an inversion of control pattern — I often write the same utility in all my REST API's, it's a utility that takes some input, validates it, passes the input to a handler, and it takes the response of the handler and passes it back to the client. The benefits of doing so are bigger than I could explain here. But this pattern creates a VERY nice separation, and creates a great central piece of code to add logging, error handling, etc. I do cover this pattern in this article: thedevcoach.co.uk/error-handling-j... ... let me know if you read it and if you have any questions.

Some other random thoughts on API building...

  • Handle errors explicitly. Any time an error can be thrown, catch it and throw an error code specific to that instance of an error. Keep these error codes unique. It'll make tracking bugs much easier in future. If you get an error without an error code, refactor and fix your code. Do this earlier rather than later.
  • Consider trying to keep storage related code separate from your business logic, avoid coupling storage concerns with business logic concerns. Keep the thought: "How hard would it be to swap database solutions?" in the back of your mind and you won't go far wrong. Don't worry about this too much, just don't litter your code with database access code.
  • Try to keep business logic separate from API specific logic, such as request validation. Keep the question: "How simple would it be to swap HTTP for RPC?" in the back of your mind and you won't go far wrong. But again, don't worry too much about it.
  • Build logging in early. Rely on your monitoring tools EARLY. Instrumenting an already built API is way harder than doing it as you go, don't forget this. Add logging as you go, practice debugging your API like it's already deployed.
  • Research REST principles and try to apply them. But don't beat yourself up when you can't always apply them, applying REST principles is like pulling the sword from the stone, let me know if you ever get it 100% right (spoiler: no-one does)
  • Look into JSON:API as a standard (there are many standards, this one is good). It will answer many questions about how to turn RESTful ideas into reality.

The main goal: If you can get your business logic to be as expressive as possible, so that it describes the custom rules of your application (when you strip away all of the technical details) you've WON the game.

Best of luck Sharad! Hit me up if you have any questions!

Collapse
 
sharadcodes profile image
Sharad Raj (He/Him)

Thank you so much 🙂, It's really helpful to me.
Yuss I'll ask more xD

Collapse
 
michi profile image
Michael Z

If you are talking about actual endpoints, have a look at this talk: Cruddy by design. If you meant code architecture, then the talk will still offer plenty of inspiration in how Laravel achieves this.

Collapse
 
sharadcodes profile image
Sharad Raj (He/Him) • Edited

Will look at it, Thanks 🙂

Collapse
 
bopinto profile image
Bernardo Oliveira Pinto

Why not follow an MVC pattern? i.e. one Controller per Entity and, in that Controller, you put all the endpoints for that entity.
Btw, this is the way Swagger generates the stubs from the APIs you design.

Collapse
 
sharadcodes profile image
Sharad Raj (He/Him)

Many have recommended swagger.
Thanks for the reply

Collapse
 
carlosfrodrigues profile image
Carlos Felix

I think the most important is separating the files into components that can change independently

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt • Edited

Perhaps follow NestJS-like pattern?

Not sure how people do on Ruby on Rails, Java Spring, or Groovy on Grails, though.

Pretty sure that HATEOAS or hypermedia is implemented in bigger frameworks.