Skip to content

Commit 5a1ae27

Browse files
committed
Centralize API base path and introduce /api/v1 versioning
1 parent ccc3e2c commit 5a1ae27

File tree

13 files changed

+41
-33
lines changed

13 files changed

+41
-33
lines changed

.envs/dev/backend.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ GITHUB_CLIENT_SECRET=your_github_oauth_app_client_secret
5151

5252
# Must match the callback URL in your GitHub App configuration
5353
# This is the backend OAuth callback endpoint that GitHub calls with the authorization code.
54-
GITHUB_REDIRECT_URL=https://127.0.0.1/auth/github/callback
54+
GITHUB_REDIRECT_URL=https://127.0.0.1/api/v1/auth/github/callback
5555

5656
# Secret used to sign OAuth "state" parameter (prevents CSRF)
5757
# Generate securely with:

.envs/dev/frontend.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
# Backend configuration
66
# -------------------------------------------------------------------
7-
VITE_API_BASE_URL=https://127.0.0.1:8000/api
7+
VITE_API_BASE_URL=https://127.0.0.1:8000/api/v1

.envs/dev_docker/backend.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ GITHUB_CLIENT_SECRET=your_github_oauth_app_client_secret
5151

5252
# Must match the callback URL in your GitHub App configuration
5353
# This is the backend OAuth callback endpoint that GitHub calls with the authorization code.
54-
GITHUB_REDIRECT_URL=https://127.0.0.1/auth/github/callback
54+
GITHUB_REDIRECT_URL=https://127.0.0.1/api/v1/auth/github/callback
5555

5656
# Secret used to sign OAuth "state" parameter (prevents CSRF)
5757
# Generate securely with:

.envs/dev_docker/frontend.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
# Backend configuration
66
# -------------------------------------------------------------------
7-
VITE_API_BASE_URL=https://127.0.0.1:8000/api
7+
VITE_API_BASE_URL=https://127.0.0.1:8000/api/v1

.envs/prod/backend.env.example

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ GITHUB_CLIENT_SECRET=your_github_oauth_app_client_secret
5151

5252
# Must match the callback URL in your GitHub App configuration
5353
# This is the backend OAuth callback endpoint that GitHub calls with the authorization code.
54-
GITHUB_REDIRECT_URL=https://127.0.0.1/auth/github/callback
54+
GITHUB_REDIRECT_URL=https://127.0.0.1/api/v1/auth/github/callback
5555
# For production, this must also point to the backend's OAuth callback endpoint
56-
# GITHUB_REDIRECT_URL=https://app.${DOMAIN}/auth/callback
56+
# GITHUB_REDIRECT_URL=https://app.${DOMAIN}/api/v1/auth/callback
5757

5858
# Secret used to sign OAuth "state" parameter (prevents CSRF)
5959
# Generate securely with:

.envs/prod/frontend.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44

55
# Backend configuration
66
# -------------------------------------------------------------------
7-
VITE_API_BASE_URL=https://127.0.0.1:8000/api
7+
VITE_API_BASE_URL=https://127.0.0.1:8000/api/v1

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ jobs:
6060
# --------------------------------------------------
6161
GITHUB_CLIENT_ID: dummy
6262
GITHUB_CLIENT_SECRET: dummy
63-
GITHUB_REDIRECT_URL: http://localhost/api/auth/github/callback
63+
GITHUB_REDIRECT_URL: http://localhost/api/v1/auth/github/callback
6464
GITHUB_STATE_SECRET_KEY: dummy
6565

6666
# --------------------------------------------------

backend/app/api/constants.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
API_PREFIX = "/api"
2+
API_VERSION = "v1"
3+
4+
API_BASE = f"{API_PREFIX}/{API_VERSION}"

backend/app/main.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from fastapi import FastAPI
22
from fastapi.middleware.cors import CORSMiddleware
33

4+
from app.api.constants import API_BASE
45
from app.core.config import settings
56
from app.core.exceptions import register_exception_handlers
67
from app.core.logger import _setup_root_logger
@@ -28,10 +29,10 @@ def create_app() -> FastAPI:
2829
)
2930

3031
# Register routers.
31-
app.include_router(simulations_router, prefix="/api")
32-
app.include_router(machine_router, prefix="/api")
33-
app.include_router(user_router, prefix="/api")
34-
app.include_router(auth_router, prefix="/api")
32+
app.include_router(simulations_router, prefix=API_BASE)
33+
app.include_router(machine_router, prefix=API_BASE)
34+
app.include_router(user_router, prefix=API_BASE)
35+
app.include_router(auth_router, prefix=API_BASE)
3536

3637
@app.get("/health")
3738
async def health():

backend/tests/features/machine/test_api.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from fastapi import HTTPException
44
from sqlalchemy.orm import Session
55

6+
from app.api.constants import API_BASE
67
from app.features.machine.api import create_machine, get_machine, list_machines
78
from app.features.machine.models import Machine
89
from app.features.machine.schemas import MachineCreate
@@ -19,7 +20,7 @@ def test_function_succeeds_with_valid_payload(self, db: Session):
1920
"notes": "Test machine",
2021
}
2122

22-
machine_create = MachineCreate(**payload)
23+
machine_create = MachineCreate(**payload) # type: ignore[arg-type]
2324
machine = create_machine(machine_create, db)
2425

2526
for key in payload:
@@ -35,7 +36,7 @@ def test_endpoint_succeeds_with_valid_payload(self, client):
3536
"notes": "Another test machine",
3637
}
3738

38-
res = client.post("/api/machines", json=payload)
39+
res = client.post(f"{API_BASE}/machines", json=payload)
3940

4041
assert res.status_code == 201
4142
data = res.json()
@@ -66,7 +67,7 @@ def test_function_raises_error_for_duplicate_name_(self, db: Session):
6667
}
6768

6869
try:
69-
machine_create = MachineCreate(**payload)
70+
machine_create = MachineCreate(**payload) # type: ignore[arg-type]
7071
create_machine(machine_create, db)
7172
except HTTPException as e:
7273
assert str(e) == "400: Machine with this name already exists"
@@ -93,7 +94,7 @@ def test_endpoint_raises_400_for_duplicate_name(self, client, db: Session):
9394
"notes": "Duplicate machine",
9495
}
9596

96-
res = client.post("/api/machines", json=payload)
97+
res = client.post(f"{API_BASE}/machines", json=payload)
9798
assert res.status_code == 400
9899
assert res.json()["detail"] == "Machine with this name already exists"
99100

@@ -128,7 +129,7 @@ def test_endpoint_successfully_list_machines(self, client):
128129
"chrysalis",
129130
}
130131

131-
res = client.get("/api/machines")
132+
res = client.get(f"{API_BASE}/machines")
132133
assert res.status_code == 200
133134
data = res.json()
134135

@@ -167,7 +168,7 @@ def test_endpoint_successfully_get_machine(self, client, db: Session):
167168
db.commit()
168169
db.refresh(expected)
169170

170-
res = client.get(f"/api/machines/{expected.id}")
171+
res = client.get(f"{API_BASE}/machines/{expected.id}")
171172
assert res.status_code == 200
172173

173174
result_endpoint = res.json()
@@ -185,6 +186,6 @@ def test_function_raises_error_if_machine_not_found(self, db: Session):
185186
def test_endpoint_raises_404_if_machine_not_found(self, client):
186187
random_id = uuid4()
187188

188-
res = client.get(f"/api/machines/{random_id}")
189+
res = client.get(f"{API_BASE}/machines/{random_id}")
189190
assert res.status_code == 404
190191
assert res.json()["detail"] == "Machine not found"

0 commit comments

Comments
 (0)