avatarGuillaume Viguier-Just

Summary

The website content outlines a pragmatic approach to deploying a serverless RESTful API on AWS using Typescript, advocating for a single GIT repository structure to streamline development and maintainability.

Abstract

The article discusses the deployment of a serverless RESTful API on Amazon Web Services (AWS) using Typescript, emphasizing the importance of a well-structured GIT repository. It suggests that a proper API specification is crucial for generating clean API documentation and that the infrastructure supporting the API should be managed through code, preferably with tools like Terraform. The author recommends a single repository for small teams, containing directories for backend, frontend, infrastructure, API specification, and tests, to ensure a cohesive development process and clean commit history. This approach is contrasted with the traditional multi-repository setup, which the author argues is less efficient for serverless applications on AWS. The article also touches on the organization of tests and infrastructure code within the repository, providing insights into best practices for managing these components.

Opinions

  • The author believes that a single repository is more beneficial than multiple repositories for small teams working on serverless RESTful APIs on AWS, as it simplifies the process of updating the API, backend, and frontend.
  • It is suggested that infrastructure as code (IaC) should be used instead of manual setup through the AWS console for better maintainability and scalability.
  • The article posits that providing client libraries in multiple languages can increase the popularity and ease of use of an API.
  • The author advises that end-to-end (E2E) tests should be separated from backend and frontend code, as they are not inherently part of either and are crucial for ensuring the API's reliability.
  • There is an emphasis on the importance of having a comprehensive set of tests, including unit, functional, and E2E tests, to make the application robust.
  • The author's preference is to include infrastructure code related to specific backend components within those component directories if the same team handles both, but to separate it into a dedicated directory if different teams are responsible for backend and infrastructure.

Pragmatic decisions for deploying a serverless RESTful API on AWS

In « Pragmatic decisions for your RESTful API », I described a set of standards and best practices that, in my opinion, you should implement if you are building a RESTful API. In this new series of posts, I will describe how to deploy a RESTful API in the serverless world on Amazon Web Services, using code written in Typescript. I will use, as a base, the famous petstore API provided as an example of an OpenAPI specification. Let’s start with the overall repository structure.

Overall GIT Repository structure

When most people create an application, they usually think they need the following : a backend and a frontend. The way it usually goes afterwards is that a myapplication-backend repository is created, and a myapplication-frontend repository is created and development can start after establishing a list of routes that will be needed for the API being created. However, when deploying a serverless RESTful API on AWS, this is only the tip of the iceberg.

Your backend and frontend are obviously important, but if you want to do things properly, you will also need :

  • a proper API specification, which will allow you to generate a clean API documentation
  • an infrastructure to support this API : API gateway, Lambdas, Cognito for the authentication, one or multiple databases etc. Note that ideally, this infrastructure should be coded using tools such as Terraform, instead of created manually through the AWS console
  • one or multiple client libraries: ideally, you are creating an API to allow other people to use it. The easier you make it for other people to use it, the more popular your API can become, so publishing one or more client libraries, eventually in multiple langages, can be a good idea
  • tests : unit and functional tests can be included in the code of your frontend and backend, but ideally, you will also have a set of E2E tests which could be separated from the code of your backend

Single vs multi repository

You could split all of these components in multiple repositories, which means you would end up with a list of the following repositories, for the petstore example :

  • petstore-backend
  • petstore-frontend
  • petstore-infra
  • petstore-spec
  • petstore-tests

If you are a small team, you will probably have a single person work on multiple parts of the application. For example, if you want to add a field to the API somewhere, you will need to update the spec, the model in the backend, and maybe display the new field in the frontend. Therefore, it will be much easier and much more convenient to work on a single repository, separating the different components using directories. This will also allow you to have a much cleaner commit history, a single commit corresponding to the addition of a specific feature in the specification, backend and frontend altogether.

That’s why, unless you really have specific teams of developers dedicated to each component I mentioned above, I really advise you to go for a single repository, named petstore, with the following directories :

-- backend
-- frontend
-- infra
-- spec
-- tests

Possible variants for tests and infra

If you have already built serverless projects, you are already probably guessing the structure that will be used for the backend : a mono-repository with a suite of packages, each package corresponding to a specific part of the application. For the petstore example we will have something like :

backend
-- common: Common files: models, helpers etc...
-- packages
---- pets
------ package.json

Here, you could argue that the infrastructure as code needed for pets could be included as sub-directories in the backend, using the following structure :

backend
-- common: Common files: models, helpers etc...
---- infra : Common infrastructure for all packages, API gateway, Cognito user pool etc.
-- packages
---- pets
------ infra : Infrastructure needed for the pets component only

Whether you choose the former or the latter is entirely up to you. If the same team of developers is responsible for the application backend and the infrastructure, it might be better to go for the latter. However, if a different team is in charge of the infrastructure and the backend, you might be better off with a single infra directory at the root of the repository.

You could argue the same thing for tests, saying they could be included in multiple directories in the backend and frontend. Let’s split the various tests you should have in your application to make it rock solid :

  • unit tests : these tests can indeed be included directly in the frontend and backend, with a specific extension. For example, if you have a Pet.ts file for your pet model, you should also have a Pet.spec.ts or Pet.test.ts for the unit tests of the Pet model.
  • functional tests : functional tests can also be included directly with specific extensions, directly in the backend and frontend of your application
  • end to end tests : that’s where things get a bit trickier. You will be testing an API, so your E2E tests should be a set of HTTP requests that will be sent to your API to verify it works as expected. You can use Postman or Insomnia to do these tests. These E2E tests will definitely need their own directory. You could include them in the backend, in a backend/tests directory, however I don’t advise you to do this : since these tests will mostly be configuration files for Postman or Insomnia, they are not really part of the backend, which is why I really advise you to put them in a tests directory at the root of the repository.

A single repository to rule them all

Unless you are a very large team, I really advise you to go for a single repository, with the following directory structure :

-- backend
-- frontend
-- infra
-- spec
-- tests

with the possibility to include the infrastructure as a code in your backend and frontend directories.

If you would like to see how you can build your API specification using OpenAPI (basically the content of the spec directory), you can refer to this article.

To learn about how you build the code of the other directories, stay tuned, more articles will follow.

Rest Api
Restful Api
AWS
Serverless
API
Recommended from ReadMedium