Integració d'un server amb Python i un client amb Typescript.

Introducció

A continuació anem a crear una aplicació web en que:

  • El servidor està escrit amb FastAPI
  • El client està escrit en React

El client i el servidor es comuniquen mitjançant JSON.

architecture-beta
   group api(internet)[Internet]
   service server(server)[Server Python] in api
   service browser(internet)[Client Typescript] in api
   browser:L --> R:server

Entorn de treball

Clona el projecte https://gitlab.com/xtec/python/vite:

$ git clone https://gitlab.com/xtec/python/vite

Servidor

El servidor es desenvolupa de manera completament independent al client.

Executa el servidor Python:

$ poetry shell
$ poetry install
$ bun run server

El servidor te configurat un endpoint a http://127.0.0.1:8000/api/time

Tots els endpoints han de començar amb /api/

Client

Executa el servidor Vite:

$ bun install
$ bun run client

Mira el fitxer vite.config.ts:

// ...
export default defineConfig({
  // ...
  server: {
    port: 3000,
    cors: true,
    proxy: {
      '/api': {
        target: 'http://localhost:8000',
      }
    },
})

El "dev server" de Vite està configurar per treballar http://127.0.0.1:8000

Pots veure que el fitxer configura un proxy en el "dev server" mitjançant l'opció server.proxy.

Totes les peticions que comencin amb /api les reenvia al la URL http://localhost:8000.

Si vas a la URL http://127.0.0.1:3000/api/time pots veure que és la mateixa resposta que dona el servidor a la URL http://127.0.0.1:8000/api/time.

Aquest proxy és completament transparent a l'aplicació React: App.tsx

  const { data, error } = useSWR("/api/time", fetcher)

Pots veure que no has de posar ni localhost ni el port on està escoltant l'aplicació server.

Producció

Quan desplegues l'aplicació, qui ha de servir tot el codi de client és el servidor.

Fes que vite construeixi l'aplicació client Vite - Build

$ bun run build

Pots veure que s'ha creat un directori server/static amb tot el contingut estàtic del client.

El servidor està configurat per servir els fitxers estàtics d'aquest directori si aquest existeix :

if os.path.exists("static"):
    app.mount("/", StaticFiles(directory="static", html=True), name="static")

Important!. Aquest codi s'ha d'afegir al final perquè la regla / sigui l'última en aplicar-se.

Torna a arrencar el servidor i ves a http://localhost:8000.

Pots veure que l'aplicació client te l'envia directament el servidor.

Docker

Crea una imatge i puja la imatge a Docker Hub.

Tens aquests dos documents d'ajuda:

Docker - BuildLes imatges es construeixen a partir d'altres imatges afegint noves capes.
Docker - RegistreUn registre és un lloc on es guarden les imatges que es fan servit per desplegar contenidors