Let's build a URL shortener in Go - Final Part : Forwarding
Throughout the previous tutorial parts, we have been able to build all the necessary components that would lead to the end goal of generating short URL and forwarding to the original url once a shortened version is provided.
For recap, you can find several previous articles from this series here :
- https://www.eddywm.com/lets-build-a-url-shortener-in-go-part-3-short-link-generation/
- https://www.eddywm.com/lets-build-a-url-shortener-in-go-with-redis-part-2-storage-layer/
- https://www.eddywm.com/lets-build-a-url-shortener-in-go/
Now it's time to put the components we built previously to good usage, so during this part we will be making sure those previously built components work together as expected.
We are going to build 2 main endpoints to our API service :
- One endpoint that will be used to generate a short url and return it, when the initial long url is provided.
/create-short-url
- The other one will be used to provide the actual redirection from the shortened version to the original longer URL.
/:short-url
IV. 1. Handlers & Endpoints
IV. 1. 1. Setup & Definitions
Without wasting more time, let's go ahead and create the handler package and define our handers functions in there.
Create a folder called handler and put in a file called handlers.go
.
After that our project directory should look like the tree below :
Now let's define our handlers stubs.
package handler
import (
"github.com/gin-gonic/gin"
)
func CreateShortUrl(c *gin.Context) {
/// Implementation to be added
}
func HandleShortUrlRedirect(c *gin.Context) {
/// Implementation to be added
}
After defining stubs, we should go straight to the main.go
file to add the needed endpoints.
Note : In more complex apps, endpoints should live in a separate file, but for the sake of simplicity and since they are just 2 endpoints, we will be having them in the main.go file
IV. 1. 2. Implementations
Now that we have defined stubs for our handlers, it's time to add the actual implementation code.
STEP 1 : We will be starting with implementing `CreateShortUrl()` handler function, this should very straightforward :
- We will getting the creation request body, parse it and extract the initial long url and userId.
- Call our
shortener.GenerateShortLink()
that we implemented in the previous PART III and generate our shortened hash. - Finally store the mapping of our output
hash/shortUrl
with the initial long url, here, we will be using thestore.SaveUrlMapping()
we implemented back in PART II
Steps 2 : The second and last step will be about implementing the redirection handler, HandleShortUrlRedirect()
, it will consist of :
- Getting the short url from the path parameter
/:shortUrl
- Call the store to retrieve the initial url that corresponds to the short one provided in the path.
- And finally apply the http redirection function
IV. 2. Testing Time 🧪
After completing the handlers implementation, now it's time to test the all thing.
- Step 1 : Run/Start the project (
main.go
file is the entry point )
A server should start at localhost:9808
- Step 2 : Request URL shortening action.
We can post the request body below to the specified endpoint.
Note that you can use any rest client you have installed locally.
The response should look like the json below :
- Step 3 : Testing the redirection.
Click on the link returned in the previous response http://localhost:9808/9Zatkhpi and check if it redirects back to the original long url.
If everything was done right, this shortened url should be able to redirect to the old initial url.
Step 2 & 3 can be repeated n times, for any any number of urls we'd like to apply shortening on.
IV. 3. Conclusion & Next Steps
If you have reached up to this point, it's fair to assume you have invested a good amount of time following up with this tutorial series, I'm really hoping you enjoyed reading and practicing along the way.
Our service is now up and running and it can shorten whatever url you throw at it.
You can find the complete project at this repository https://github.com/eddywm/go-shortener-wm.
A few improvements that can be added as voluntary next steps :
- Dockerize and deploy the service in the cloud.
- Add a SQL DB (Postgres or Mysql) as backup to the Redis main store, that should be used for store of cold values/least frequently fetched data.
- Build a minimal front-end that would be consuming this service.
If you have any feedback, questions or request regarding tutorial series you want me to write about, please feel free to contact me via Twitter or Email.
Ciao ! 👋