Integration of a Python server and a Typescript client using Vite and a development proxy.
Introduction
Ee will create a web application in which:
The client and server communicate using JSON.
Working environment
Clone the project:
$ git clone https://gitlab.com/xtec/python/viteServer
The backend server is developed completely independently of the frontend.
Start the Python server through the Deno task:
$ deno task serverThe server exposes an HTTP endpoint at:
All API endpoints must start with /api/
Client
Now start the Typescript - Vite development server:
$ deno task clientHave a look at the file vite.config.ts:
// ...export default defineConfig({ // ... server: { port: 3000, cors: true, proxy: { '/api': { target: 'http://localhost:8000', } },})The Vite dev server runs on http://127.0.0.1:3000 and is configured to proxy API requests to the backend server on http://127.0.0.1:8000.
This is done using the server.proxy option. All HTTP requests whose path starts with /api are forwarded transparently to http://localhost:8000.
If you open:
you will see the same response as the backend endpoint:
From the React application’s point of view, this proxy is completely transparent. In
App.tsx you can see a data fetch like this:
const { data, error } = useSWR("/api/time", fetcher)Notice that:
- You do not specify
localhost. - You do not specify any port.
- You only use the path (
/api/time).
Production
In production, the backend server must serve both:
- All API endpoints.
- All static client assets (the built React application).
First, build the client application with Vite(Vite - Build):
$ deno task buildThis creates a directory with all the static assets for the client, typically placed under server/static (depending on the project configuration).
The server is configured to serve static files from this directory if it exists, for example:
You can see that a server/static directory has been created with all the static content of the client.
The server is configured to serve the static files from this directory if it exists:
if os.path.exists("static"): app.mount("/", StaticFiles(directory="static", html=True), name="static")This code must be added at the end of the route configuration so that the
/ rule is applied last, after the API routes.
Restart the server and go to:
You should now see the client application being served directly by the backend server. The same origin (http://127.0.0.1:8000) is used for both the API (/api/...) and the frontend (static files).
Docker
Finally, package the application into a container image and push it to Docker Hub.
You can follow these two help documents: