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

API params serializer #449

Merged
merged 4 commits into from
Jul 10, 2023
Merged

API params serializer #449

merged 4 commits into from
Jul 10, 2023

Conversation

nicolasguridi
Copy link
Contributor

@nicolasguridi nicolasguridi commented Jul 7, 2023

Context

Potassium-generated applications use APIs to send and receive data between their backend and their frontend. Since both sides use different case conventions for hash keys, a conversion is required for each data exchange.

In #412, an API client was added to the frontend that included case conversion for request bodies. But request query params still don't have case conversion, so it's implemented wherever necessary, usually resulting in code repetition.

What has been done

Summary:
A params serializer has been added to the frontend API client that converts the params casing as needed.

To implement this, a query params util was created with one feature: converting an object into a valid URL query string, with keys in snake_case.

Commits:

  1. Adds the qs dependency to the frontend, to handle the conversion of objects into valid query params.
  2. Creates a query-params util, to take a JavaScript object and return a valid URL query string with snake_case keys.
  3. Include params serialization in the frontend's API client, to apply the param serialization in every request made from that client.

Extra info

The qs library was used for stringifying params because it was suggested in Axios docs and looks well maintained. If we don't want to add an extra dependency, it could be replaced by a custom solution, but it will probably be less robust.

@nicolasguridi nicolasguridi marked this pull request as ready for review July 7, 2023 21:03
@nicolasguridi nicolasguridi requested a review from gmq July 7, 2023 21:03
import { decamelizeKeys } from 'humps';
import { stringify } from 'qs';

export function serializeParams(params: Record<string, string | number | undefined>) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe these types are too limited, it should be able to handle nested arrays and objects (for example when making requests to Ransack)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True, changed it to object. Hope I didn't overcompensate

@@ -16,6 +17,7 @@ const api = axios.create({
'Accept': 'application/json',
'X-CSRF-Token': csrfToken(),
},
paramsSerializer: (params) => serializeParams(params),
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this could be simplified to paramsSerializer: serializerParams since it's passing the same argument. Or serializerParams could be renamed to paramsSerializer to use the shorthand.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice, I'll go with the shorthand 👌

@nicolasguridi nicolasguridi force-pushed the feat/api-params-serializer branch from b86fe7f to d1d6993 Compare July 7, 2023 22:11
@nicolasguridi nicolasguridi requested a review from gmq July 7, 2023 22:14
export function paramsSerializer(params: object) {
const decamelizedParams = decamelizeKeys(params);

return stringify(decamelizedParams, { arrayFormat: 'repeat' });
Copy link
Contributor

@gmq gmq Jul 7, 2023

Choose a reason for hiding this comment

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

Sorry, didn't see this before. I think it has to be brackets here to get the usual array[]=1&array[]=2 format rails uses

Copy link
Contributor Author

@nicolasguridi nicolasguridi Jul 7, 2023

Choose a reason for hiding this comment

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

Oh, good catch. I thought it didn't matter but never tested it 😬

@nicolasguridi nicolasguridi force-pushed the feat/api-params-serializer branch from d1d6993 to dfc1e9a Compare July 7, 2023 22:25
@nicolasguridi nicolasguridi requested a review from gmq July 7, 2023 22:26
@nicolasguridi nicolasguridi merged commit b0be1d2 into master Jul 10, 2023
@nicolasguridi nicolasguridi deleted the feat/api-params-serializer branch July 10, 2023 13:22
@nicolasguridi nicolasguridi changed the title Feat/api params serializer API params serializer Aug 18, 2023
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.

2 participants