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

feat: add-api-proxy: Add Nitro server API routes #179

Merged
merged 34 commits into from
Jan 31, 2024
Merged

Conversation

vloss3
Copy link
Contributor

@vloss3 vloss3 commented Oct 19, 2023

Solves #165

src/module.ts Outdated Show resolved Hide resolved
src/module.ts Outdated Show resolved Hide resolved
@@ -12,7 +12,11 @@ export const useDrupalCe = () => {
* @returns UseFetchOptions<any>
*/
const processFetchOptions = (fetchOptions:UseFetchOptions<any> = {}) => {
fetchOptions.baseURL = fetchOptions.baseURL ?? config.baseURL
if (config.exposeAPIRouteRules) {
fetchOptions.baseURL = useRequestURL().origin + '/api/drupal-ce'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, if this function is called from fetchMenu, then instead of '/api/drupal-ce', baseURL should be '/api/menu'. That way, we make use of the menu proxy defined in routeRules.
I'm fine with using just one simple flag, e.g. isFetchMenu, to know when to apply '/api/menu'.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a path prefix and a baes url are two different things. maybe the code should be re-factored into a helper. different topic.

@TurtlBbx
Copy link
Contributor

@vloss3 Once the improvements are done, could you add a test case for when the exposeAPIRouteRules option is set to false. It can be a copy of https://github.com/drunomics/nuxtjs-drupal-ce/blob/2.x/test/basic.test.ts with the exposeAPIRouteRules set to false.

@TurtlBbx
Copy link
Contributor

@vloss3 README needs to be updated as well for this feature.

README.md Outdated Show resolved Hide resolved
src/module.ts Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
@vloss3
Copy link
Contributor Author

vloss3 commented Nov 21, 2023

The following was discussed to move forward with this feature:

New options:

  • drupalBaseUrl: origin URL, for iframes and other cases, changeable via env variable
  • serverDrupalBaseUrl: http://node (optional: use this during server render if set))
  • ceApiEndpoint: /ce-api (default)
  • menuEndpoint: unchanged
  • menuBaseUrl: http://domain.com/ce-api (default: drupalUrl + ceApiEndpoint), changeable via env variable

Note: Those options will have defaults and will not require configuration changes

Route rules changes:

  • remove /api/drupal
  • convert route rules to nitro server routes

Use cases to consider:

  • proxy files through frontend
  • add an iframe of drupal in the frontend project code

Tests and customizing cache rules(by project) will be carried in follow-up issues.

@fago
Copy link
Contributor

fago commented Dec 5, 2023

@vloss3 I updated README slightly. I was not sure about DRUPAL_BASE_URL - do we still support that variable actually? Since there is built-in support in nuxt to override config via NUXT_PUBLIC_... I could see us dropping that + documenting that instead.

@vloss3 vloss3 force-pushed the feature/165-add-api-proxy branch from 3f77d1f to bee448c Compare December 6, 2023 19:10
src/runtime/composables/useDrupalCe.ts Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated

Runtime config values can be overridden with environment variables via `NUXT_PUBLIC_` prefix. Supported runtime overrides:

- `baseUrl` -> `NUXT_PUBLIC_DRUPAL_CE_BASE_URL`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this documents an override for the deprecated optiln. it should document it for drupalbaseUrl

Copy link
Contributor

@TurtlBbx TurtlBbx Jan 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fago @vloss3 In code, we don't support ENV override of drupalBaseUrl. It's not taken into account, as seen here.

We either:
a) Change back in README to state that we support baseUrl (and not drupalBaseUrl) override (it's used in the server proxy handler).
b) Change the code to support drupalbaseUrl override and leave the README as-is.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • We need to have that kind of override working, this is critical functionaliaty, we cannot merge without it.
  • The module had code merge in runtimeconfig and make it override regular config before. maybe this is still there and working?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed drupalBaseUrl to work with env overrides


export default defineEventHandler(async (event) => {
const drupalCe = useRuntimeConfig().public.drupalCe
const menuBaseUrl = drupalCe.serverDrupalBaseUrl || drupalCe.menuBaseUrl
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should primarily use the configured menuBaseUrl and fallback to serverDrupalBaseURL.

src/module.ts Show resolved Hide resolved
export default defineEventHandler(async (event) => {
const path = `/${event.context.params._.replace('api/drupal-ce', '')}`
const drupalCe = useRuntimeConfig().public.drupalCe
const drupalBaseUrl = drupalCe.serverDrupalBaseUrl || drupalCe.baseURL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a correct fallback which is missing at the menu route


export default defineEventHandler(async (event) => {
const drupalCe = useRuntimeConfig().public.drupalCe
const menuBaseUrl = drupalCe.menuBaseUrl || drupalCe.serverDrupalBaseUrl
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

serverDrupalBaseUrl is not required, so not enough as fallback


export default defineEventHandler(async (event) => {
const drupalCe = useRuntimeConfig().public.drupalCe
const menuBaseUrl = drupalCe.serverDrupalBaseUrl || drupalCe.menuBaseUrl
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vloss3 This is wrong I think:
const menuBaseUrl = drupalCe.serverDrupalBaseUrl || drupalCe.menuBaseUrl
It should be:
const menuBaseUrl = drupalCe.menuBaseUrl || (drupalCe.serverDrupalBaseUrl || drupalCe.drupalBaseUrl) + drupalCe.ceApiEndpoint
Because serverDrupalBaseUrl and drupalBaseUrl contains no ceApiEndpoint postfix.

README.md Show resolved Hide resolved
src/module.ts Outdated
import { defineNuxtModule, addPlugin, createResolver, addImportsDir } from '@nuxt/kit'
import { UseFetchOptions } from 'nuxt/dist/app/composables'
import { defineNuxtModule, addPlugin, createResolver, addImportsDir, addServerHandler } from '@nuxt/kit'
import type { UseFetchOptions } from 'nuxt/dist/app/composables'
import { defu } from 'defu'

export interface ModuleOptions {
baseURL: string,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is optional actually, since deprecated

src/module.ts Outdated
import { defu } from 'defu'

export interface ModuleOptions {
baseURL: string,
drupalBaseUrl?: string,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is required now. can we mark it so or will that be a BC-issue?

import { useRuntimeConfig } from '#imports'

export default defineEventHandler(async (event) => {
const path = `/${event.context.params._.replace('api/drupal-ce', '')}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hard to read. better use '/' + ...
also, it's not safe. it should remove the prefix characters only, e.g. a fixed not number of chars - not remove any occurrences of this string.

export default defineEventHandler(async (event) => {
const { serverDrupalBaseUrl, drupalBaseUrl, menuBaseUrl, ceApiEndpoint } = useRuntimeConfig().public.drupalCe
const menuUrl = menuBaseUrl || (serverDrupalBaseUrl || drupalBaseUrl) + ceApiEndpoint
const menu = event.context.params._
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that normal? _ parameter is very very strange and not readable. does it have no proper API to get a parameter in readable away?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is getRouterParams(event) which also returns _, will use this method


export default defineEventHandler(async (event) => {
const { serverDrupalBaseUrl, drupalBaseUrl, menuBaseUrl, ceApiEndpoint } = useRuntimeConfig().public.drupalCe
const menuUrl = menuBaseUrl || (serverDrupalBaseUrl || drupalBaseUrl) + ceApiEndpoint
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: menuBaseUrl.
the menu url would already incldue the menu name

@@ -101,6 +109,10 @@ export const useDrupalCe = () => {
const baseMenuPath = config.menuEndpoint.replace('$$$NAME$$$', name)
const menuPath = ref(baseMenuPath)

if (config.exposeAPIRouteRules) {
useFetchOptions.baseURL = useRequestURL().origin + '/api/menu'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, I do still think this is problematic. if run on a CDN, the original url will be the wrong one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it has to be the original url as the server route request gets forwarded as well:
cdn-domain.com/api/drupal-ce -> localhost:3000/api/drupal-ce

so it seems to work? I've tested this with a nginx reverse proxy behind Cloudflare

@@ -12,7 +12,11 @@ export const useDrupalCe = () => {
* @returns UseFetchOptions<any>
*/
const processFetchOptions = (fetchOptions:UseFetchOptions<any> = {}) => {
fetchOptions.baseURL = fetchOptions.baseURL ?? config.baseURL
if (config.exposeAPIRouteRules) {
fetchOptions.baseURL = useRequestURL().origin + '/api/drupal-ce'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a path prefix and a baes url are two different things. maybe the code should be re-factored into a helper. different topic.

src/runtime/composables/useDrupalCe.ts Outdated Show resolved Hide resolved
@vloss3 vloss3 merged commit af80b10 into 2.x Jan 31, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants