How to define queries in my Route?

Hello everyone :slight_smile:

I would like to know how to define queries in my Route ?

For example, I wrote those lines in the routes.php :

return [
  'routes' => [
                // routes
    		[
			'name' => 'space#getByName',
			'url' => '/workspaces?search={name}',
			'verb' => 'GET'
		],
  ]
];

Here is the content of my getByName function from the SpaceController :

    /**
     * @NoAdminRequired
     * @NoCSRFRequired
     */
    public function getByName(string $name): DataResponse
    {
        $space = $this->spaceMapper->findByName($name);

        if (is_null($space)) {
            return new DataResponse([
                'message' => 'Nothing space.'
            ], Http::STATUS_NOT_FOUND);
        }

        return new DataResponse($space);
    }

But, when I send my request with Insomnia, I got this error message :

However, if I define my route as follows : /workspaces/search/{name}. It works !

So, I don’t know if it’s possible to define queries ? :thinking:

I didn’t see any reference to this in the documentation : Routing — Nextcloud latest Developer Manual latest documentation

You can access the query part for sure. It is documented in the controller: Controllers — Nextcloud latest Developer Manual latest documentation

However, it seems strange to me that you run into CSRF issues. Did you really use the same code and retry or did you register two ropes and copy the code over? The CSRF check should be independent of and routing issues and only checks for the annotation/attribute @NoCsrfCheck.

Hi @christianlupus :slight_smile:

Thanks for your answer :slight_smile:

No, it’s the same code I used it.

To be honest, in my routes.php, I have two routes that starts with “/spaces” :

 return [
	'routes' => [
            // code
	      [
			'name' => 'space#getByName',
			'url' => '/spaces?search={name}',
			'verb' => 'GET'
	     ],
             [
			'name' => 'workspace#findAll',
			'url' => '/spaces',
			'verb' => 'GET'
	    ],
];

So, if I understand, if I want to have the /spaces?search={name} route. I must write /spaces and define the parameter on the front-end side ?
However, I cannot have 2 routes with /spaces. I have to keep this route :

 return [
	'routes' => [
            // code
             [
			'name' => 'workspace#findAll',
			'url' => '/spaces',
			'verb' => 'GET'
	    ],
];

But, Does it make sense to have one single route (/spaces) to get all workspaces or one workspace with the search as parameter (example : /spaces?search={name}) ? :thinking:

Phew, I am not sure what will happen there. I would have to dig into the routing routines in the server to understand that in detail. At least, I was careful as this is not done as documented.

I am not sure, I get your point. You will always have to adopt the frontend to the backend. So, yes this is always true that you must add the parameters in the frontend in some way…

This might be discussable. Does it make sense? You could have a /spaces for all spaces and /search/{name} or /search?q={name} or /spaces/search?q={name} or anything else that can be uniquely distinguished. That might be a bit cleaner in terms of API anyways. You can still call similar service methods in the backend to avoid duplicate code.

If you really want to do things in one controller method, you could add an optional parameter name in the query string and give it a default of e.g. null. Then, you can check in the method for null (return all entries). If it is non-null, carry out the requested search.