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

Allow LinkVariables to support multiple values with the same key #421

Closed
dayre opened this issue Jan 14, 2022 · 7 comments · Fixed by #444
Closed

Allow LinkVariables to support multiple values with the same key #421

dayre opened this issue Jan 14, 2022 · 7 comments · Fixed by #444

Comments

@dayre
Copy link
Collaborator

dayre commented Jan 14, 2022

Really enjoying building a client side data access layer using Ketting, thank you for making it !

Have an issue at the moment supporting sort using multiple fields. My backend is a Spring Data Rest, and the method for sorting by multiple fields is to repeat the "sort" parameter for each field (e.g. ?sort=name,asc&sort=created,desc).

I'm using the LinkVariables param on the follow() method in Resource, but it is defined as a map and doesn't permit duplicate keys.

Since there doesn't look to be anything in the RFC for query params that disallows multiple values, i'm thinking LinkVariables should be redefined to support this.

Looking at the API, I don't see any workarounds that would allow me to make this happen... unless you have any suggestions ?

@evert
Copy link
Collaborator

evert commented Jan 14, 2022

Thanks for the nice words!

Ah interesting. What would the URI Template look like for these?

@dayre
Copy link
Collaborator Author

dayre commented Jan 14, 2022

This is an example from my "clients" link. Page,size,projection are single values, whereas sort can be a collection/multiple.
"clients": { "href": "http://localhost:8080/api/clients{?page,size,sort,projection}", "templated": true },

Spring documents it here: https://docs.spring.io/spring-data/rest/docs/current/reference/html/#repository-resources.collection-resource.supported-methods.get :

"A collection of sort directives in the format ($propertyname,)+[asc|desc]?."

@evert
Copy link
Collaborator

evert commented Jan 14, 2022

I wonder if we could just type LinkVariables as:

/**
 * A key->value map of variables to place in a templated link
 */
export type LinkVariables = {
  [key: string]: string | number | (string|number)[]
};

@dayre
Copy link
Collaborator Author

dayre commented Jan 14, 2022

Ok, interesting rabbit hole, just delved into the URI template RFC. I think your suggested change is needed and will work.

The issue is that Spring data expects multivalues for sort to be "expanded" by duplicating the key for each entry. (see https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#core.web.basic, Table 1).

If i use the template provided by Spring, i get the following:

const templ = uriTemplate.parse("http://localhost:8080/api/clients{?page,size,sort,projection}");
const expanded = templ.expand({sort : ["id,asc", "lastModifiedDate,desc"]});

// http://localhost:8080/api/clients?sort=id%2Casc,lastModifiedDate%2Cdesc

Spring doesn't parse this properly and the sort direction for the params isn't handled properly (they both end up with a sort direction of "DESC").

If i modify the template to include the expansion modifier (*) for sort in the URI template, i get what Spring expects:

const templ = uriTemplate.parse("http://localhost:8080/api/clients{?page,size,sort*,projection}");
const expanded = templ.expand({sort : ["id,asc", "lastModifiedDate,desc"]});

// http://localhost:8080/api/clients?sort=id%2Casc&sort=lastModifiedDate%2Cdesc

This works great and Spring is happy, all is good with the world.

So given your suggested change, and the proper template i should be able to generate the URL Spring expects. I still need to follow up to see why Spring isn't providing the expansion modifier on the sort variable which i think it should be, but for this issue if your change is made that should do it.

@dayre
Copy link
Collaborator Author

dayre commented Jan 15, 2022

For reference, anyone else dealing with this issue when using your spectacularly amazing stupendous library and the lack of an explosion modifier for the sort parameter generated by Spring, i've opened an issue here:

spring-projects/spring-data-commons#2531

@qmachard
Copy link
Contributor

qmachard commented Jun 8, 2022

I wonder if we could just type LinkVariables as:

/**
 * A key->value map of variables to place in a templated link
 */
export type LinkVariables = {
  [key: string]: string | number | (string|number)[]
};

Yes, it works !

@evert evert closed this as completed in #444 Jun 8, 2022
@dayre
Copy link
Collaborator Author

dayre commented Jan 20, 2023

Hi Evert, i don't see this commit in any releases, it's not in 7.5.1. Did it get overlooked ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants