Commit 87c3017c authored by Andre Blanke's avatar Andre Blanke
Browse files

Improve documentation

parent cafbed64
......@@ -5,12 +5,14 @@
| HTTP method | Target URL | Description |
|-------------|-------------|-----------------------------------------------------------------------------------------|
| GET | /index.html | Angular frontend of the URL shortener with an input for a URL that should be shortened. |
| GET | / | Alias for GET /index.html. |
| GET | /$id | Redirects the browser to the URL associated with the provided $id. |
| POST | /?url=$url | Endpoint used for the creation of a new id associated with the provided $url. |
## GET /index.html
Retrieves the Angular frontend of the URL shortener located under `/frontend` inside the project structure.
Retrieves the Angular frontend of the URL shortener located under `/shortener/src/main/angular/shortener` inside the
project structure.
The frontend gives users the ability to input URLs which should be shortened by our service.
......@@ -20,7 +22,7 @@ handled: display an error message if a shortened URL could not be created or dis
More features such as the following could also be added to `/index.html`:
- A way of not only creating a short URL with a randomly generated `$id` but one with a custom `$id` chosen by the
user.
user (implemented).
- Maybe an account system which would allow users to optionally login. A logged in user could see all the URLs that
have been shortened while they were logged in and they might have the ability to remove certain short URLs or
......@@ -29,9 +31,7 @@ More features such as the following could also be added to `/index.html`:
- An administrator view that displays a table of all short URLs and their target information, optionally with the same
detail logged in users can see for their short URLs, plus maybe a list of users.
The last two points would require an account system. Login would happen using an email and a password for example.
The frontend should be served directly using the Apache Web Server without a detour over Django.
The last two points would require an account system. Login would happen using an e-mail and a password for example.
## GET /$id
......@@ -40,7 +40,7 @@ to it.
This endpoint will be used by clients who have been given a shortened URL and want to visit the original URL behind it.
Because this operation requires a database lookup, Django will be required to serve the `/$id` endpoint.
Because this operation requires (or might require) a database lookup, Spring will be required to serve the `/$id` endpoint.
## POST /?url=$url[&id=$id]
......@@ -53,16 +53,27 @@ Some things will need to be considered when generating new ids or accepting cust
- The id needs to be reachable. If one could create a redirect with an id of `index.html` either our frontend or the
link associated with that id would not be reachable.
- The id should be easy to type, i.e. contain no special characters and not be case-sensitive.
- The id should be easy to type, i.e. contain no special characters and not be case-sensitive. For this purpose we
have chosen an id which follows a pattern of `[a-z0-9]`. A mixture of upper and lower case characters is avoided
like this which is beneficial when spelling out the id, as confusions between upper and lower case characters are
avoided.
- The ids should most likely not be sequential, as this could be used to find the previous id and thus the URL behind
it. While this service is of course not one used for privacy that should still not be possible.
- It would at least be advantageous if the ids were not sequential, as this could be used to find the previous id
and thus the URL behind it. This, however, is certainly not critical, as the service should of course not be used
for privacy reasons.
Additionally, the concepts of uniqueness of ids, their shortness and the performance of their generation are seemingly
opposed.
The current implementation does not satisfy this criteria, as the ids are generated sequentially.
Care must be taken when specifying `$url`: The provided URL needs to be URL-encoded or should maybe be part of the
payload instead of the URL. If the specified URL were not URL-encoded we would not be able to tell whether
Care must be taken when specifying the `$url` parameter: The provided URL needs to be URL-encoded or should maybe be
part of the payload instead of the URL. If the specified URL were not URL-encoded we would not be able to tell whether
`/?url=https://www.example.com?id=example` is a request to create a short URL to `https://www.example.com` under the
id `example` or to `https://www.example.com?id=example` under a random id, as both would have the same representation.
See [this Stackoverflow answer](https://stackoverflow.com/a/58756335) for an example of how to URL-encode from the
frontenv using `encodeURIComponent`.
This endpoint also needs to be served by Django because, again, database operations are required.
This endpoint also needs to be served by Spring because, again, database operations are possibly required.
The id-URL mapping created by a POST call may be cached. Reasoning here is the principle of temporal locality, as one
would expect a shortened URL to be used shortly after its creation rather than later. In case of a cache hit we could
spare the additional database hit.
......@@ -62,6 +62,30 @@ provided URL. The short URL containing the ID is then returned back to the clien
Accessing the short URL will then cause a redirect to the associated long URL stored in the database.
### The frontend
The frontend consists of a rather minimal Angular project located at `/shortener/src/main/angular/shortener`.
Originally the plan was to serve the frontend using an Apache HTTP Server instance located on each
worker server but due to configuration issues (and a tight-ish time budget) this could not realized.
Instead a Tomcat instance now serves both static files as well as API requests.
![Image of the web frontend](.github/images/frontend.png)
### The backend
While a Django application was planned due to the fact that everyone on our team had at least some
experience with Python the idea was later scrapped: not everyone would end up working on the backend
part of the application and those who would had their focus and experience in other languages and
frameworks.
The idea of a Django-based backend turned into that of a Spring Boot-based backend with the code
written in [Kotlin](https://en.wikipedia.org/wiki/Kotlin_(programming_language)).
The project is built using Apache Maven, with the frontend included into the packaged JAR file,
and is fully self-contained (besides the JRE required to run it).
A systemd unit, `shortener.service`, is responsible for launching the application.
## Deployment
The project is currently deployed using an embedded Tomcat instance, the default embedded server used
......
`ng serve --port 8080 --host 0.0.0.0 --disable-host-check`
......@@ -3,6 +3,14 @@ package xyz.upbshrt.shortener.controller
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
/**
* [Controller] responsible for serving the `index.html` file under the path `/`.
*
* For some reason this controller is required even though `index.html` should by default be served via Spring Boot
* (with `/` being redirected accordingly).
* A potential cause for that issue may be the HTTP POST mapping that is already defined for `/` inside the
* [UrlShorteningController].
*/
@Controller
class IndexController {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment