Skip to content

Commit

Permalink
feat: create proxy to serve lazy loaded assets
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelovicentegc committed Jun 24, 2024
1 parent c717beb commit c983ac4
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 24 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ It is ideal if you want to bootstrap a blog or a portfolio website quickly, or e
- [Setting up a database](#setting-up-a-database)
- [Setting up a CDN](#setting-up-a-cdn)
- [Running the project](#running-the-project)
- [Application architecture \& features](#application-architecture--features)
- [Application architecture](#application-architecture)
- [Features](#features)
- [Frontend](#frontend)
- [Backend](#backend)
- [Integrations](#integrations)
Expand Down Expand Up @@ -64,7 +65,11 @@ pnpm dev:full # Starts the project while assuming you've setup a database using

By default, the frontend app will run on `localhost:4000` and the backend app will run on `localhost:8000`. If you're running the containerized Postgres, it will run on `localhost:5432` and pgAdmin will run on `localhost:5050`.

## Application architecture & features
It's important to note that for the best development experience, you should run the backend and frontend apps separately. This way, you can take advantage of the hot-reload feature from Webpack and Django's development server.

Although you can replicate the aforementioned behavior on a production environment (run the backend and frontend apps on differen servers), **this project is built to run both apps on the same server, with the frontend app being served by Django's templates and view engine**. You can learn more about how this works below 👇

## Application architecture

This application's architect is quite simple and leverages the best of both Django and React. On a nutshell, React and Django integrate through Django's Views and Django Rest Framework's API endpoints.

Expand All @@ -83,6 +88,8 @@ flowchart TD
n0 -- Consumes API Key\nto authenticate\nwith backend --> ng
```

## Features

Below you will find the stack used for each part of the application and the features that are already implemented.

### Frontend
Expand Down
10 changes: 0 additions & 10 deletions core/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,6 @@
'cloudinary'
]

# https://github.com/cdrx/django-admin-menu

ADMIN_STYLE = {
'primary-color': '#164B36',
'secondary-color': '#092117',
'tertiary-color': '#51B48E'
}

ADMIN_LOGO = 'backend/logo.png'

SITE_ID = 1

MIDDLEWARE = [
Expand Down
1 change: 0 additions & 1 deletion frontend/apps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from django.apps import AppConfig


class FrontendConfig(AppConfig):
name = 'frontend'
2 changes: 1 addition & 1 deletion frontend/templates/frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
<body>
<div id="root"></div>
</body>
<script src="{% static "frontend/index.js" %}"></script>
<script src="{% static "frontend/index.js" %}" defer type="text/javascript"></script>
<noscript>Javascript is not enabled on your browser</noscript>
</html>
8 changes: 4 additions & 4 deletions frontend/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from django.urls import path, re_path
from django.urls import re_path
from . import views


urlpatterns = [
re_path(r'^biography$|^blog$|^$', views.index, name='frontend'),
re_path(r'^blog/(?P<string>.+)$|^$', views.blog_post, name='frontend')
re_path(r'^blog$|^$', views.index, name='frontend'),
re_path(r'^blog/(?P<string>.+)$|^$', views.blog_post, name='frontend'),
re_path(r'^.*\.js$', views.js_files_handler, name='frontend'),
]
36 changes: 32 additions & 4 deletions frontend/views.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,44 @@
import requests
from django.shortcuts import render
from core.settings.base import PRODUCTION_MODE
from django.shortcuts import redirect
from django.http import StreamingHttpResponse
from wsgiref.util import is_hop_by_hop

class ProxyHttpResponse(StreamingHttpResponse):
def __init__(self, url, headers=None, **kwargs):
upstream = requests.get(url, stream=True, headers=headers)

kwargs.setdefault('content_type', upstream.headers.get('content-type'))
kwargs.setdefault('status', upstream.status_code)
kwargs.setdefault('reason', upstream.reason)

super().__init__(upstream.raw, **kwargs)

for name, value in upstream.headers.items():
if not is_hop_by_hop(name):
self[name] = value


def index(request):
endpoint = request.META.get('PATH_INFO', None)
pathname = request.META.get('PATH_INFO', None)

if (endpoint == '/admin'):
if (pathname == '/admin'):
return redirect('/admin/')

return render(request, 'frontend/index.html')


def blog_post(request, string):
return render(request, 'frontend/index.html')
return render(request, 'frontend/index.html')


def js_files_handler(request):
pathname = request.META.get('PATH_INFO', None)
url = request.build_absolute_uri()

backend_relative_pathname = pathname.replace('/', '/static/frontend/')
url = url.replace(pathname, backend_relative_pathname)

print(url)

return ProxyHttpResponse(url, headers=request.headers)
2 changes: 1 addition & 1 deletion frontend/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ module.exports = {
loader: "file-loader",
options: {
name: "icons|fonts/[name].[ext]",
outputPath: "assets",
outputPath: PUBLIC_PATH,
},
},
],
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
"scripts": {
"bootstrap": "concurrently -n global,backend,frontend \"pnpm i\" \"poetry install\" \"cd frontend && pnpm i\"",
"setup:env": "sh ./scripts/setup_env.sh",
"build:frontend": "cd frontend && pnpm i && pnpm run build",
"dev:db:up": "docker compose -f ./docker-compose-dev-db.yml up",
"dev:db:migrate": "poetry run python3 manage.py migrate",
"dev:db:makemigrations": "poetry run python3 manage.py makemigrations",
"dev:backend": "poetry run python3 manage.py runserver",
"dev:backend": "pnpm run build:frontend && poetry run python3 manage.py runserver",
"dev:backend:db": "concurrently -n db,backend \"pnpm run dev:db:up\" \"wait-on tcp:5432 && pnpm run dev:backend\"",
"dev:frontend": "cd frontend && pnpm i && pnpm run dev",
"dev": "concurrently -n backend,frontend \"pnpm run dev:backend\" \"pnpm run dev:frontend\"",
Expand Down

0 comments on commit c983ac4

Please sign in to comment.