Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Web] Allow to configure api base url / port through env var #198

Open
wants to merge 1 commit into
base: web/react
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 43 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,53 @@ vhs.sh:
# Web #
#######

## Web - Start web server (PORT)
web: PORT = 9400
web:
echo Start web server...
## Web - Install
web.install:
go install
$(MAKE) --directory web/app install
.PHONY: install

web: web.serve

## Web - Start api web server + React app (PORT)
web.serve: PORT = 9400
web.serve:
# https://www.npmjs.com/package/concurrently
npx concurrently "make web.serve.api+local PORT=$(PORT)" "make web.serve.front API_PORT=$(PORT)" \
--names="API,Front" \
--prefix=name \
--prefix-colors="auto" \
--kill-others \
--kill-others-on-fail \
--colors
.PHONY: web.serve

## Web - Start front (React) app only (API_PORT)
web.serve.front: API_PORT = 9400
web.serve.front:
echo Start front server...
$(MAKE) --directory web/app serve API_PORT=$(API_PORT)
.PHONY: web.serve.front

## Web - Start api web server only (requires go) (PORT)
web.serve.api+local: PORT = 9400
web.serve.api+local:
echo Start api server...
go run \
-tags web_app_build \
. \
web --debug --port $(PORT)
.PHONY: web.serve.api+local

## Web - Start api web server only using Docker (PORT)
web.serve.api+docker: PORT = 9400
web.serve.api+docker:
echo Start api server...
docker compose run --rm \
--publish $(PORT):$(PORT) \
go \
go run \
-tags web_app_build \
. \
web --debug --port $(PORT)
.PHONY: web
.PHONY: web.serve.api+docker
19 changes: 19 additions & 0 deletions web/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Web

Manala WEB API + UI.

## Development

From project root, start both the API + front app with:

```shell
make web.install web.serve
```

> **Note**: you'll need Go to be installed on your machine:
>
> OS X users:
>
> ```shell
> brew install go
> ```
9 changes: 6 additions & 3 deletions web/app/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ install@integration:
update:
npm update

## Serve - Serve
## Serve - Serve (API_PORT, API_BASE_URI)
serve: export API_PORT = 9400
serve: export API_BASE_URI = http://localhost:$(API_PORT)/api
serve:
npx webpack serve \
--mode=development \
--mode=development

## Build - Build
## Build - Build (API_BASE_URI)
build: export BUILD = 1
build: export API_BASE_URI = http://localhost:9400/api
build:
npx webpack \
--mode=production
Expand Down
11 changes: 10 additions & 1 deletion web/app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,16 @@ import { RouterProvider } from 'react-router-dom';
import { router } from '@app/router';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();
const queryClient = new QueryClient({
defaultOptions: {
queries: {
// https://tanstack.com/query/v4/docs/react/guides/window-focus-refetching
refetchOnWindowFocus: false,
// https://tanstack.com/query/v4/docs/react/guides/query-retries
retry: false,
},
},
});

export default function App() {
return <QueryClientProvider client={queryClient}>
Expand Down
5 changes: 5 additions & 0 deletions web/app/src/AppConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type AppConfigScheme = {
API_BASE_URI: string
}

export default AppConfig as AppConfigScheme;
7 changes: 7 additions & 0 deletions web/app/src/globals.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { AppConfigScheme } from '@app/AppConfig';

declare global {
const AppConfig: AppConfigScheme;
}

export {};
8 changes: 5 additions & 3 deletions web/app/src/pages/RecipeList.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React from 'react';
import { Grid, List, ListItemButton, ListItemText, Skeleton, Stack, Typography } from '@mui/material';
import { Alert, Grid, List, ListItemButton, ListItemText, Skeleton, Stack, Typography } from '@mui/material';
import { useNavigate } from 'react-router-dom';
import { route, Routes } from '@app/router';
import { useQuery } from '@tanstack/react-query';
import { jsonApiQuery } from '@app/utils/api';

export default function RecipeList() {

const { isLoading, isError, data } = useQuery({
queryKey: ['repoData'],
queryFn: () => fetch('http://localhost:9400/api/recipes').then((res) => res.json()),
queryKey: ['recipes'],
queryFn: jsonApiQuery('/recipes'),
});

const recipes = data;
Expand Down Expand Up @@ -37,6 +38,7 @@ export default function RecipeList() {
<Skeleton variant="rectangular" width={210} height={60} />
<Skeleton variant="rectangular" width={210} height={60} />
</Stack>}
{isError && <Alert severity="error">An error occurred while fetching the data</Alert>}
{!isLoading && !isError && <List>
{recipes.map((recipe) =>
<ListItemButton
Expand Down
19 changes: 19 additions & 0 deletions web/app/src/utils/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ltrim, rtrim } from '@app/utils/strings';
import AppConfig from '@app/AppConfig';

/**
* Composes the URI of an API resource with base API URI.
*/
export function apiUri(path: string): string {
return [
rtrim(AppConfig.API_BASE_URI, '/'),
ltrim(path, '/'),
].join('/');
}

/**
* Returns a function that fetches a JSON API resource.
*/
export function jsonApiQuery(path: string) {
return () => fetch(apiUri(path)).then((res) => res.json());
}
7 changes: 7 additions & 0 deletions web/app/src/utils/strings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function ltrim(str: string, charlist: string) {
return str.replace(new RegExp(`^[${charlist}]+`), '');
}

export function rtrim(str: string, charlist: string) {
return str.replace(new RegExp(`[${charlist}]+$`), '');
}
ogizanagi marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 6 additions & 0 deletions web/app/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const path = require('path');
const { DefinePlugin } = require('webpack');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
Expand Down Expand Up @@ -75,6 +76,11 @@ module.exports = (argv) => {
]
},
plugins: [
new DefinePlugin({
AppConfig: JSON.stringify({
API_BASE_URI: process.env.API_BASE_URI,
}),
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'public/index.html'),
publicPath: '/',
Expand Down