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

feat: Domains API operations #208

Merged
merged 1 commit into from
Feb 1, 2024
Merged

feat: Domains API operations #208

merged 1 commit into from
Feb 1, 2024

Conversation

gkats
Copy link
Member

@gkats gkats commented Jan 31, 2024

Type of change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • 🌟 New feature (non-breaking change which adds functionality)
  • 🔨 Breaking change (fix or feature that would cause existing functionality)
  • 📖 Docs change / refactoring / dependency upgrade to change)

Description

Added types for Domains.

Added a new package for Domains API operations. Supports List, Create, Update and Delete.

@gkats gkats requested a review from a team as a code owner January 31, 2024 15:50
@gkats gkats force-pushed the core-1512-domains branch from 2a2f9b5 to 89cbad2 Compare January 31, 2024 18:48
Copy link
Contributor

@georgepsarakis georgepsarakis left a comment

Choose a reason for hiding this comment

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

👏

@@ -258,7 +258,7 @@ func (b *defaultBackend) do(req *http.Request, params Queryable, setter Response
func setRequestBody(req *http.Request, params Queryable) error {
// GET requests don't have a body, but we will pass the params
// in the query string.
if req.Method == http.MethodGet {
if req.Method == http.MethodGet && params != nil {
q := req.URL.Query()
params.Add(q)
Copy link
Contributor

Choose a reason for hiding this comment

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

❓ I just noticed this and I'm not sure I understand it 100%. This also allows for some room for someone to erroneously tamper with the q object, if they implement their own custom struct, isn't that right? I would probably expect it to be the other way round, but let me know what you think (and this goes up to the APIRequest struct I believe):

func setRequestBody(req *http.Request, params url.Values) error {
  if req.Method == http.MethodGet && params != nil {
    q := req.URL.Query()
    for key, values := range params {
       for _, v := range values {
         q.Add(key, v)
       }
    }

The Queryable interface could be then:

type Queryable interface {
  ToQueryParameters() url.Values
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Great point! I'll update the interface and the logic. I'd rather do it on a separate PR. Do you think that would be a problem?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not a problem at all, by all means proceed with merging 🚀

@@ -0,0 +1,25 @@
package clerk
Copy link
Contributor

Choose a reason for hiding this comment

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

❓ Couldn't we use the domain package here instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

We could, but I'm afraid that at some point we might need this type from another package. Imagine an Instance which has a nested Domain.

I believe it's safer to have these types for "models" in the clerk package so we don't run into any circular dependecy problem in the future.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, I thought that we might want to reuse structs. Do you think that if we introduced a models/<service> kind of structure, we might run into circular dependency problems? Just thinking out loud here:

import (
  domainmodels "github.com/clerk/clerk-sdk-go/v2/models/domains"
)

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! Your solution would certainly avoid circular dependency, but isn't it a bit too much packaging?

Is there any reason why using the clerk package might be problematic?

Copy link
Contributor

Choose a reason for hiding this comment

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

It's not problematic, it's only that packages provide a native namespace and the import aliases provide some more naming flexibility for someone that uses them. Names also become more uniform.

package domain

// Debatable name :)
type Object struct{}
type List struct {
  Data []Object `json:"data"`
}
import (
  domainmodels "github.com/clerk/clerk-sdk-go/v2/models/domains"
) 

func HandleDomains() {
  var domainList domainmodels.List
  //...
}

Just an idea here, not insisting on this, it might be overly verbose/complicated for some reason. Noting now, since it would be a breaking change afterwards!

}

// List returns a list of domains
func List(ctx context.Context, params *ListParams) (*clerk.DomainList, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

🔧 If there's not a strong reason to use pointers, I think we should avoid them where possible, as they make garbage collection more difficult and the risk of accidental mutations increases.

domain/domain_test.go Show resolved Hide resolved
}

func (rt *mockRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
if rt.status == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Mostly a suggestion, it might be easier to use a constructor for initializations: newMockRoundTripper

domain/domain_test.go Show resolved Hide resolved
domain/domain_test.go Show resolved Hide resolved
domain/domain_test.go Show resolved Hide resolved
domain/domain_test.go Show resolved Hide resolved
clerk.SetBackend(clerk.NewBackend(&clerk.BackendConfig{
HTTPClient: &http.Client{
Transport: &mockRoundTripper{
T: t,
Copy link
Contributor

Choose a reason for hiding this comment

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

🔧 Don't you want to assert that the GET method is used here?

HTTPClient: &http.Client{
Transport: &mockRoundTripper{
T: t,
out: json.RawMessage(`{
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 You can also introduce a helper here:

out: MustJSONMarshal(clerk.DomainList{}),

Since JSON serialization/deserialization is generally symmetric, I think this doesn't break the expectation validity here.

Added types for Domains. Added a new package for Domains API operations.
Supports List, Create, Update and Delete.
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 this pull request may close these issues.

2 participants