From 8a12c3de68586b0714fd5f95f0f2fd746e7892fc Mon Sep 17 00:00:00 2001 From: Guilherme Mierzwa Date: Thu, 19 Oct 2023 05:09:45 -0300 Subject: [PATCH] feat(orval): allow custom baseUrl for each OpenAPI specification (#968) --- docs/src/pages/guides/set-base-url.md | 62 ++++++++++++++++++++++++--- packages/core/src/types.ts | 2 + packages/orval/src/api.ts | 9 +++- packages/orval/src/utils/options.ts | 1 + 4 files changed, 66 insertions(+), 8 deletions(-) diff --git a/docs/src/pages/guides/set-base-url.md b/docs/src/pages/guides/set-base-url.md index 3796789bc..52872f8de 100644 --- a/docs/src/pages/guides/set-base-url.md +++ b/docs/src/pages/guides/set-base-url.md @@ -1,16 +1,30 @@ ## Use your own base url -orval doesn't set any base url by default but you have multiple possibility to add it +Orval allows you to set a custom base url for each OpenAPI specification. This can be a part of the url that's been omitted from the specification or the entire url. + +```ts +module.exports = { + petstore: { + output: { + target: 'src/petstore.ts', + baseUrl: '/api/v2', + // baseUrl: 'https://petstore.swagger.io/v2', + }, + }, +}; +``` + +It's also possible to configure the base url directly on your HTTP client instead. ### Axios -You can set a default baseUrl +You can set a default baseUrl for all requests: ```ts -Axios.defaults.baseURL = ''; // use your own URL here or environment variable +axios.defaults.baseURL = ''; // use your own URL here or environment variable ``` -You can also use an interceptor to do it +You can also use an interceptor to do it: ```ts axios.interceptors.request.use((config) => { @@ -21,16 +35,50 @@ axios.interceptors.request.use((config) => { }); ``` -There is also the possibilty to create a custom axios instance +There is also the possibility to create a custom axios instance. Check the [full guide](../guides/custom-axios.md) for more details. ```ts -const AXIOS_INSTANCE = Axios.create({ baseURL: '' }); // use your own URL here or environment variable +const AXIOS_INSTANCE = axios.create({ baseURL: '' }); // use your own URL here or environment variable ``` ### Angular http client You can use an interceptor to automatically add the url of your API. Like you would do to add an authorization header. +```ts +import { Injectable } from '@angular/core'; +import { + HttpEvent, + HttpInterceptor, + HttpHandler, + HttpRequest, +} from '@angular/common/http'; +import { Observable } from 'rxjs/Observable'; + +@Injectable() +export class APIInterceptor implements HttpInterceptor { + intercept( + req: HttpRequest, + next: HttpHandler, + ): Observable> { + const apiReq = req.clone({ url: `/${req.url}` }); + return next.handle(apiReq); + } +} +``` + +Also remember to add the interceptor to your providers in your module. + +```ts +providers: [ + { + provide: HTTP_INTERCEPTORS, + useClass: APIInterceptor, + multi: true, + }, +]; +``` + ### Other client -Depending the client that you are using you will need to add it by yourself +Depending on the client that you are using, you will need to add it by yourself diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 7076e32ca..1b34a2c26 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -52,6 +52,7 @@ export type NormalizedOutputOptions = { packageJson?: PackageJson; headers: boolean; indexFiles: boolean; + baseUrl?: string; }; export type NormalizedOverrideOutput = { @@ -165,6 +166,7 @@ export type OutputOptions = { packageJson?: string; headers?: boolean; indexFiles?: boolean; + baseUrl?: string; }; export type SwaggerParserOptions = Omit & { diff --git a/packages/orval/src/api.ts b/packages/orval/src/api.ts index 39b2fe898..731f62d73 100644 --- a/packages/orval/src/api.ts +++ b/packages/orval/src/api.ts @@ -95,11 +95,18 @@ export const getApiBuilder = async ({ [] as GeneratorSchema[], ); + let fullRoute = route; + if (output.baseUrl) { + if (output.baseUrl.endsWith('/') && route.startsWith('/')) { + fullRoute = route.slice(1); + } + fullRoute = `${output.baseUrl}${fullRoute}`; + } const pathOperations = await generateOperations( output.client, verbsOptions, { - route, + route: fullRoute, pathRoute, override: output.override, context: resolvedContext, diff --git a/packages/orval/src/utils/options.ts b/packages/orval/src/utils/options.ts index 2ded7e8ff..a158fea6d 100644 --- a/packages/orval/src/utils/options.ts +++ b/packages/orval/src/utils/options.ts @@ -121,6 +121,7 @@ export const normalizeOptions = async ( packageJson, headers: outputOptions.headers ?? false, indexFiles: outputOptions.indexFiles ?? true, + baseUrl: outputOptions.baseUrl, override: { ...outputOptions.override, mock: {