Where Should the ASP.NET Core API URL Be Configured in Angular?
1. What is the API URL?
The API URL is the base address Angular uses to communicate with the ASP.NET Core Web API.
For example:
Development:
https://localhost:7001/api
UAT:
https://uat-api.jntech.in/api
Production:
https://api.jntech.in/api
You should not hard-code the base URL repeatedly inside Angular services.
Instead, for build-time configuration, keep it in Angular's environment-specific configuration.
2. Full Simple Sample
Project Structure
src/
├── app/
│ ├── models/
│ │ └── product.ts
│ └── services/
│ └── product.ts
│
└── environments/
├── environment.ts
├── environment.uat.ts
└── environment.production.ts
environment.ts — Development
export const environment = {
production: false,
apiUrl: 'https://localhost:7001/api'
};
environment.uat.ts — UAT
export const environment = {
production: false,
apiUrl: 'https://uat-api.jntech.in/api'
};
environment.production.ts — Production
export const environment = {
production: true,
apiUrl: 'https://api.jntech.in/api'
};
product.ts
export interface Product {
id: number;
name: string;
price: number;
}
services/product.ts
import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Product } from '../models/product';
import { environment } from '../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class ProductService {
private http = inject(HttpClient);
private apiUrl = `${environment.apiUrl}/products`;
getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(this.apiUrl);
}
getProduct(id: number): Observable<Product> {
return this.http.get<Product>(`${this.apiUrl}/${id}`);
}
addProduct(product: Product): Observable<Product> {
return this.http.post<Product>(this.apiUrl, product);
}
updateProduct(id: number, product: Product): Observable<void> {
return this.http.put<void>(
`${this.apiUrl}/${id}`,
product
);
}
deleteProduct(id: number): Observable<void> {
return this.http.delete<void>(
`${this.apiUrl}/${id}`
);
}
}
3. Why Configure the URL in the Environment?
Suppose you hard-code this:
private apiUrl =
'https://localhost:7001/api/products';
This works locally.
But after deploying Angular to production, Angular would still try to call:
https://localhost:7001
That is incorrect.
Instead:
private apiUrl =
`${environment.apiUrl}/products`;
Now the base URL can change according to the build environment.
4. How Does Angular Select the URL?
Your application always imports:
import { environment }
from '../../environments/environment';
You don't normally write logic such as:
if (production) {
// use production URL
} else {
// use development URL
}
The build configuration selects the appropriate environment file.
Conceptually:
ProductService
│
▼
environment.apiUrl
│
├── Development
│ ↓
│ https://localhost:7001/api
│
├── UAT
│ ↓
│ https://uat-api.jntech.in/api
│
└── Production
↓
https://api.jntech.in/api
5. Development Build
Run:
ng serve --configuration development
The service effectively uses:
apiUrl: 'https://localhost:7001/api'
Therefore:
this.http.get<Product[]>(
`${environment.apiUrl}/products`
);
calls:
https://localhost:7001/api/products
6. Production Build
Run:
ng build --configuration production
The production configuration can replace the development environment file with:
environment.production.ts
Therefore:
environment.apiUrl
becomes:
https://api.jntech.in/api
and the same service calls:
https://api.jntech.in/api/products
No change to ProductService is required.
7. Configure angular.json
For example:
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.production.ts"
}
]
},
"uat": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.uat.ts"
}
]
}
}
Then:
ng build --configuration uat
uses:
environment.uat.ts
while:
ng build --configuration production
uses:
environment.production.ts
8. Don't Repeat the Base URL in Every Service
Avoid this:
// ProductService
private apiUrl =
'https://localhost:7001/api/products';
// CustomerService
private apiUrl =
'https://localhost:7001/api/customers';
// OrderService
private apiUrl =
'https://localhost:7001/api/orders';
Better:
// environment.ts
export const environment = {
apiUrl: 'https://localhost:7001/api'
};
Then:
// ProductService
private apiUrl =
`${environment.apiUrl}/products`;
// CustomerService
private apiUrl =
`${environment.apiUrl}/customers`;
// OrderService
private apiUrl =
`${environment.apiUrl}/orders`;
Now the common base URL is maintained in one place.
9. What If Angular Calls Multiple ASP.NET Core APIs?
You can configure multiple URLs:
export const environment = {
production: false,
productApiUrl: 'https://localhost:7001/api',
orderApiUrl: 'https://localhost:7002/api',
authApiUrl: 'https://localhost:7003/api'
};
Then:
private apiUrl =
`${environment.productApiUrl}/products`;
and:
private apiUrl =
`${environment.orderApiUrl}/orders`;
This is common with microservices or multiple backend APIs.
10. Important: API URL Is Not a Secret
It is perfectly normal for Angular to contain:
apiUrl: 'https://api.jntech.in/api'
The API URL itself is normally public information because the browser must know where requests are being sent.
However, don't put secrets in Angular:
export const environment = {
apiUrl: 'https://api.jntech.in/api',
// DON'T DO THIS
sqlPassword: 'mypassword',
jwtSigningKey: 'secret',
privateApiKey: 'secret123'
};
Angular executes in the user's browser, so bundled configuration can be inspected.
11. Build-Time vs Runtime Configuration
There is one important architectural consideration.
Environment files are primarily build-time configuration.
For example:
ng build --configuration uat
creates a UAT-specific build.
Then:
ng build --configuration production
creates a production-specific build.
So you may have:
Source Code
│
├── UAT Build
│ ↓
│ UAT API URL
│
└── Production Build
↓
Production API URL
If your deployment requirement is:
Build once and deploy exactly the same Angular artifact to DEV, SIT, UAT and Production
then runtime configuration is generally more appropriate.
For example:
Angular
↓
config.json
↓
API URL
The deployment process can supply a different config.json for each environment without rebuilding Angular.
Key Points
- The ASP.NET Core API base URL should not be hard-coded throughout Angular services.
- For straightforward build-time configuration, keep it in Angular environment configuration:
export const environment = {
apiUrl: 'https://localhost:7001/api'
};
- Access it using:
environment.apiUrl
- Development and production can have different URLs.
angular.jsonbuild configurations can usefileReplacements.- API URLs are generally not secrets.
- Passwords, JWT signing keys, connection strings, and private API keys must not be stored in Angular.
- If you need build once → deploy everywhere, consider runtime configuration instead of environment-file replacement.
Interview Questions and Answers
1. Where should the ASP.NET Core API URL be configured in Angular?
For build-time configuration, the API base URL can be stored in Angular's environment-specific configuration and accessed through environment.apiUrl.
apiUrl: 'https://localhost:7001/api'
2. Why shouldn't we hard-code the API URL in Angular services?
Because the URL usually changes between Development, UAT, and Production. Centralized configuration makes deployment and maintenance easier.
3. How do you access the API URL inside a service?
import { environment }
from '../../environments/environment';
private apiUrl =
`${environment.apiUrl}/products`;
4. Can Angular have multiple API URLs?
Yes. For example:
export const environment = {
productApiUrl: 'https://product-api.example.com/api',
orderApiUrl: 'https://order-api.example.com/api'
};
This is useful when Angular communicates with multiple backend services.
5. Is it safe to store an API URL in Angular?
Yes, generally. The browser must know the endpoint it is calling. However, credentials and secrets must never be placed in client-side Angular configuration.
6. Should the API URL be stored in appsettings.json?
For the ASP.NET Core application's own configuration, appsettings.json is appropriate. But an Angular SPA does not directly read ASP.NET Core's appsettings.json; Angular needs its own build-time or runtime configuration mechanism.
7. What is the best approach if the same Angular build must be deployed to UAT and Production?
Use runtime configuration rather than compiling the API URL directly into the Angular bundle:
One Angular Build
↓
Runtime Configuration
↓
┌─────┴─────┐
UAT Production
↓ ↓
UAT API Prod API
This allows the same Angular artifact to be promoted through environments without rebuilding it.