The backend of this project can be found in the api
directory.
It consists of a few parts. This page will go some way to explain the different parts, and how they fit together.
This is the file we run when we want to start our server. It does two things:
- Connect to the Postgresql database.
- Creates our application
- Configures CORS settings.
- Sets up our api routes at
/users
,/posts
and/tokens
- Start our app, listening for incoming HTTP requests.
Our routes define the different request URLs that our api will respond to. They also define which controllers will handle which requests. Each file in the routes directory defines one route, with multiple endpoints.
For example, posts.go
creates two routes:
- POST
<BACKEND_URL>/posts
to create a new post withcontrollers.CreatePost
- GET
<BACKEND_URL>/posts
to get all posts withcontrollers.GetAllPosts
Controllers contain the functions that actually handle the requests that our app recieves. Each controller is a function that takes one argument, the Gin context. This struct has information about the request, and methods and fields we can use to send a response.
The full list of features can be found here.
We can also add data to the ctx
struct with middleware, such as the
AuthenticationMiddleware
adding the user_id
property, which can then be used
by controller functions.
We can respond to requests using the ctx.JSON
method to send a JSON string.
Our models are structs that handle interaction with the database. We create our models using a library called Gorm. Each model is created with a declaration, which defines the shape of the data in the database, ie. what fields the entries in our database have.
These structs provide built-in methods, such as .First
,
.Last
and .Find
. More info can be found
here.
To create entries in the database, we create a struct, and use the .Save
function:
testPost := models.Post{
Message: fmt.Sprintf("This is a test message created at %v!", time.Now()),
}
testPost.Save()
Middleware are similar to our controller handler functions, but don't
necessarily end with a response. Instead they call a next
method to pass on to
the next handler.
For example, the AuthenticationMiddleware
makes sure that the request has been
sent with a vaild token. If it has, it passes on to the next handler, such as
the posts router. If it has an invalid token, it will send an error response
back to the client.
The lib directory simply contains functions which can be used from anywhere in our app, for handling authentication.
This is a small package for loading environment variables.