adonisjs / core

AdonisJS is a TypeScript-first web framework for building web apps and API servers. It comes with support for testing, modern tooling, an ecosystem of official packages, and more.
https://adonisjs.com
MIT License
16.92k stars 640 forks source link

Problem Generating Routes with Router.builder in Imported Routes #4456

Closed leofmarciano closed 7 months ago

leofmarciano commented 7 months ago

Package version

@adonisjs/core@6.2.2

Describe the bug

We've identified a potential bug in the route creation process using router.builder(). It seems related to the order of its use. When used directly in start/routes.ts, it works as expected. However, moving the same piece of code into folders, such as routes/v1/verify_account.ts, it stops working as expected, returning the error "Cannot lookup route".

We tested by copying and pasting directly from the documentation, as shown in the images.

The issue occurs when trying to generate the route using the URL Builder. If the route is directly in routes.ts, it functions normally. However, attempting to use it by importing routes from a file, like routes/v1/verify_account.ts, results in the error.

It doesn't seem like it was intended to work this way.

Environment and Version

Steps to Reproduce

  1. Create an AdonisJS project, a controller or use case, and implement the makeSignedUrl code as per the documentation.
  2. Create two routes as per the documentation of router.builder().
  3. Access the route that leads to the controller to execute the function of router.builder().

Expected Behavior

Generate a signed route, which can be used to validate information, access, email, and so on.

Current Behavior

Besides the "Cannot lookup route" error.

Code Examples

//start/routes.ts
/*
|--------------------------------------------------------------------------
| Routes file
|--------------------------------------------------------------------------
|
| The routes file is used for defining the HTTP routes.
|
*/

import './routes/v1/signup.ts'
import './routes/v1/signin.ts'
import './routes/v1/verify_account.ts'
//start/routes/v1/verify_account.ts
import { middleware } from '#start/kernel'
import router from '@adonisjs/core/services/router'

const version = 'v1'

router
  .group(() => {
    router
      .get('unsubscribe/:id', ({ request, response }) => {
        if (!request.hasValidSignature()) {
          return response.badRequest('Invalid or expired URL')
        }
      })
      .as('unsubscribe')
  })
  .prefix(`api/${version}/verify-account/`)
  .domain(':tenant.casify.test')
  .use(middleware.switchTenant())
//app/usecases/email/post_signup.ts
import router from '@adonisjs/core/services/router'

export default async function sendPostSignUpEmail() {
  try {
    const url = await router.builder().params({ id: 231 }).makeSigned('unsubscribe')
    console.log(url)
    return true
  } catch (error) {
    console.log(error)
    return error
  }
}

Error

Cannot lookup route "unsubscribe"
    at RouteFinder.findOrFail ([OMITTED]/adonisjs/node_modules/@adonisjs/http-server/src/router/lookup_store/route_finder.ts:49:13)
    at UrlBuilder.makeSigned ([OMITTED]/adonisjs/node_modules/@adonisjs/http-server/src/router/lookup_store/url_builder.ts:227:39)
    at sendPostSignUpEmail ([OMITTED]/adonisjs/app/usecases/email/post_signup.ts:5:60)
    at CreateUserUseCase.execute ([OMITTED]/adonisjs/app/usecases/signup/create_user.ts:20:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at SignUpService.execute ([OMITTED]/adonisjs/app/services/signup_service.ts:47:23)
    at SignupController.create ([OMITTED]/adonisjs/app/controllers/authentication/signup_controller.ts:26:14)
    at SwitchTenantMiddleware.handle ([OMITTED]/adonisjs/app/middleware/switch_tenant_middleware.ts:56:5) {
  status: 500,
  code: 'E_CANNOT_LOOKUP_ROUTE'
}

Reproduction repo

No response

RomainLanz commented 7 months ago

Hey @leofmarciano! 👋🏻

Since your route is inside a specific domain, you need to specify it.

router
  .builderForDomain('blog.adonisjs.com')
  .params({ id: 1 })
  .make('posts.show')

📚 https://docs.adonisjs.com/guides/url-builder#making-url-for-routes-under-a-domain