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

✨ v3 (feature): request binding #2006

Draft
wants to merge 28 commits into
base: main
Choose a base branch
from
Draft

✨ v3 (feature): request binding #2006

wants to merge 28 commits into from

Conversation

trim21
Copy link
Contributor

@trim21 trim21 commented Aug 8, 2022

Please provide enough information so that others can review your pull request:

related to #1821 and #2002

Explain the details for making this change. What existing problem does the pull request solve?

this PR add a function decorator style bind method to provide high speed and low alloc request binding.

this PR add a high performance and low alloc binding implement.

some changes:

  1. data[]=john&data[]=doe won't bind to query:"data", only bind to query:"data[]" and can't bind query like data[0]=john&data[1]=doe
  2. you can't used multiple tag together, only one of them will work.
  3. function decorators will panic if any misused happened (eg req is not a struct type). I think there is no meaning to return a error because developer must change their code instead of handling there errors.

TODO:

  • document
  • better error message
  • bind request body
  • validate
  • form
  • multipart
  • Add some of old methods like GetHeaders etc.
  • Pointer support for struct fields.
  • Multipart file binding
  • Add more tests and benchmarks.
  • Better nested binding behavior like current binding
    • Support nested.and.age, nested.age queries
    • Support data[0][name] queries
    • Support data[0][users][0][name] queries
    • Support data.0.name queries (we can convert dots to square brackets or the opposite)

@trim21 trim21 changed the title WIP: V3 request bind [WIP] ✨ v3 (feature): request bind Aug 8, 2022
@trim21 trim21 changed the title [WIP] ✨ v3 (feature): request bind [WIP] ✨ v3 (feature): request binding Aug 8, 2022
@trim21 trim21 changed the title [WIP] ✨ v3 (feature): request binding ✨ v3 (feature): request binding Aug 8, 2022
@trim21

This comment was marked as outdated.

@trim21 trim21 marked this pull request as ready for review August 9, 2022 02:42
@efectn efectn added this to the v3 milestone Aug 11, 2022
@efectn efectn linked an issue Aug 11, 2022 that may be closed by this pull request
3 tasks
@trim21
Copy link
Contributor Author

trim21 commented Aug 19, 2022

shoule we hide the original unmarshal message from encoding.TextUnmarshaler.UnmarshalText or strconv.Parse{Int|Uint|Bool}?

@efectn
Copy link
Member

efectn commented Aug 20, 2022

I reviewed this a bit today and this way seems good to me but i have a little question. Why don't we support map binding? I think we can add map support when checking the type in compiler.go

@efectn
Copy link
Member

efectn commented Aug 20, 2022

And we don't need default validator i think. Playground validator has too much and big sized indirect dependencies (gin-gonic/gin#3165). But we can support custom validators by an struct validator interface.

@trim21

This comment was marked as outdated.

@trim21
Copy link
Contributor Author

trim21 commented Aug 20, 2022

Why don't we support map binding

I think we can add old methods like ctx.GetRespHeaders back for this use case.

@trim21 trim21 marked this pull request as draft August 22, 2022 03:41
@trim21 trim21 marked this pull request as ready for review August 23, 2022 09:40
@trim21
Copy link
Contributor Author

trim21 commented Aug 23, 2022

This PR only add JSON and XML body type, The multipart and form body need a new decoder, I'll add them in the next PR.

Copy link
Member

@efectn efectn left a comment

Choose a reason for hiding this comment

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

I added some comments. Maybe i can add some comments more in next days. Looks like great PR 🚀🚀

internal/reflectunsafe/reflectunsafe.go Outdated Show resolved Hide resolved
binder.go Show resolved Hide resolved
binder_compile.go Outdated Show resolved Hide resolved
binder_test.go Outdated Show resolved Hide resolved
ctx.go Outdated Show resolved Hide resolved
Copy link
Member

@efectn efectn left a comment

Choose a reason for hiding this comment

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

Btw we can try to implement form, multipart form in this pr

@FGYFFFF
Copy link

FGYFFFF commented Jan 11, 2023

hey, all ~ @trim21 @efectn , If the field of the structure is an array, do we need to support it?

@trim21
Copy link
Contributor Author

trim21 commented Jan 11, 2023

hey, all ~ @trim21 @efectn , If the field of the structure is an array, do we need to support it?

it's already supported in this PR I think...

https://github.com/gofiber/fiber/blob/081809e8a69649fafb59fa11dd629e9d00117a7a/bind_readme.md#quick-start

at least for (req/res)headers and query. And path param can't present an array.

@FGYFFFF
Copy link

FGYFFFF commented Jan 11, 2023

	var req struct {
		Data []struct {
			Name string `query:"name"`
			Age  int    `query:"age"`
		} `query:"data"`
	}

I read the source code, "Slice" already supports it, but "Array" doesn't seem to support it yet. like blow

	type Req struct {
		ID1 [5]string `query:"id"`
	}

will occur a error for “unsupported type [5]string”.
@trim21

@trim21
Copy link
Contributor Author

trim21 commented Jan 11, 2023

	var req struct {
		Data []struct {
			Name string `query:"name"`
			Age  int    `query:"age"`
		} `query:"data"`
	}

I read the source code, "Slice" already supports it, but "Array" doesn't seem to support it yet. like blow

	type Req struct {
		ID1 [5]string `query:"id"`
	}

will occur a error for “unsupported type [5]string”. @trim21

Oh, sorry... I'm think slice .....

@trim21
Copy link
Contributor Author

trim21 commented Jan 11, 2023

	var req struct {
		Data []struct {
			Name string `query:"name"`
			Age  int    `query:"age"`
		} `query:"data"`
	}

I read the source code, "Slice" already supports it, but "Array" doesn't seem to support it yet. like blow

	type Req struct {
		ID1 [5]string `query:"id"`
	}

will occur a error for “unsupported type [5]string”. @trim21

I don't think it's a bad idea, but should it return a validation error when trying to bind q=1&q=2 to [5]int?

@FGYFFFF
Copy link

FGYFFFF commented Jan 11, 2023

	var req struct {
		Data []struct {
			Name string `query:"name"`
			Age  int    `query:"age"`
		} `query:"data"`
	}

I read the source code, "Slice" already supports it, but "Array" doesn't seem to support it yet. like blow

	type Req struct {
		ID1 [5]string `query:"id"`
	}

will occur a error for “unsupported type [5]string”. @trim21

I don't think it's a bad idea, but should it return a validation error when trying to bind q=1&q=2 to [5]int?

yes~ like gin (https://github.com/gin-gonic/gin/blob/3010cbd7f4eccdbb610c510274895e083b8c058c/binding/form_mapping.go#L184), it will determine the length of the array in advance.
If possible, I can finish this FEATURE

@trim21
Copy link
Contributor Author

trim21 commented Jan 11, 2023

yes~ like gin (https://github.com/gin- gonic/gin/blob/3010cbd7f4eccdbb610c510274895e083b8c058c/binding/form_mapping.go#L184), it will determine the length of the array in advance.
If possible, I can finish this FEATURE

I'm not against this feature or you adding it in this PR, but if possible I'd like to get this PR merged first...

@FGYFFFF
Copy link

FGYFFFF commented Jan 11, 2023

to get this PR merged first

I'm not trying to grab this PR, I just found some problems in the process of research, so I raised it.
Sorry, maybe because my description was not clear

@trim21
Copy link
Contributor Author

trim21 commented Jan 11, 2023

to get this PR merged first

I'm not trying to grab this PR, I just found some problems in the process of research, so I raised it. Sorry, maybe because my description was not clear

No... I didn't mean that. That's ok if you want to add feature or finish this PR, or even just re-open a new PR based on this one, it's not a problem to me.

I'm lack of time in these months and this pr bas been stalling for a while. I'm saying that because I hope you can also help finishing it 😥

@FGYFFFF
Copy link

FGYFFFF commented Jan 12, 2023

ok~😄😄😄

@FGYFFFF
Copy link

FGYFFFF commented Jan 13, 2023

So far, I have found some feature that need to be added in:

  • Array
  • multiple pointer (gin supported, does fiber need to support?)
  • customized type bind panic

I will complete these FEATURES in my free time.

@ReneWerner87
Copy link
Member

@FGYFFFF how far are you ?

@FGYFFFF
Copy link

FGYFFFF commented Feb 7, 2023

@FGYFFFF how far are you ?

I'll do it as soon as I can, maybe in two weeks.

@ReneWerner87
Copy link
Member

ok perfect, thx

@ReneWerner87
Copy link
Member

ReneWerner87 commented Jan 17, 2024

@trim21 @efectn
what tasks are still open here? we can now pay more attention to v3

can you merge/refresh again ? and document the last open points so that we can actively help here or find decisions

Copy link
Contributor

coderabbitai bot commented Mar 16, 2024

Important

Auto Review Skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository.

To trigger a single review, invoke the @coderabbitai review command.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit-tests for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

@ReneWerner87
Copy link
Member

todos:

  • Nested structs are supported. However nested slice structs are not supported. slice field decoder needs to be rewrited for that case
  • We need to make more check for pointer usage cases
  • we need to support files

@ReneWerner87
Copy link
Member

@coderabbitai can you suggest solutions for the open todos

Can you also check the existing code

Copy link
Contributor

coderabbitai bot commented Mar 24, 2024

Tip

For best results, initiate chat on the files or code changes.

@ReneWerner87, after running the script to search for relevant files, it appears there are multiple references to pointers, files, and nested structures within the codebase. This indicates that the codebase already has some handling for these concepts, but improvements or additional features might still be needed based on the open todos.

Given the complexity and breadth of the codebase, here are more detailed suggestions for each open todo based on the script's findings:

  1. Nested Slice Structs: The codebase likely already handles nested structures to some extent. Enhancing support for nested slice structs could involve refining the recursive decoding logic to better handle slices of structs, ensuring that each element in the slice is properly decoded.

  2. Pointer Usage Cases: The references to pointers suggest that there's already some handling of pointers in the code. Improving this could involve ensuring that all pointer-related edge cases are covered, such as correctly initializing nil pointers and handling pointer-to-pointer scenarios. Adding targeted unit tests for these cases could help ensure robustness.

  3. File Support: The numerous references to file handling indicate that file support is already a significant part of the codebase. Enhancing file support could involve adding more comprehensive handling for multipart file uploads, including better error handling, support for large files, and possibly integrating with external storage solutions for file uploads.

For a more detailed review and specific code changes, it would be beneficial to closely examine the implementation of these features in the context of the current codebase and consider how they align with the project's overall architecture and design goals.

If there are specific areas of the code or features you'd like me to focus on, please let me know, and I can provide more targeted advice or suggestions.

Analysis chain

@ReneWerner87, I've outlined potential solutions for the open todos:

  1. Nested Slice Structs: Enhance the decoder to recursively handle nested slice structs. This involves detecting fields that are slices of structs during decoding and applying the decoding logic to each element in the slice.
  2. Pointer Usage Cases: Implement comprehensive checks for pointer fields to ensure correct handling of nil pointers and proper dereferencing. Adding tests for various pointer scenarios is also recommended.
  3. File Support: For file uploads, consider handling multipart/form-data content types by parsing multipart form data, extracting file metadata and content, and providing an API for accessing uploaded files.

To provide a more detailed review of the existing code, I've initiated a script to search for relevant files. I'll follow up with more specific insights or recommendations based on the findings.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Check for the presence of files related to the todos mentioned in the comment.
# This includes looking for files that might be related to nested structs, pointer usage, and file support.
fd --type f --exec grep -E "nested struct|pointer|file" {}

Length of output: 28118

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

🚀 v3 Request: New Parser for Binding
4 participants