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

Add email template endpoints #251

Merged
merged 5 commits into from
May 8, 2018
Merged

Conversation

joshcanhelp
Copy link
Contributor

  • Adding GET, PATCH, and POST for email templates API
  • Adding tests for these new methods
  • Added a more IDE-friendly method to create an ApiClient
  • Added static methods to the ApiTest class to allow for fixture setup

@joshcanhelp joshcanhelp added this to the v5-Next milestone Apr 22, 2018
Copy link
Contributor

@lbalmaceda lbalmaceda left a comment

Choose a reason for hiding this comment

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

It feels a little simple because the methods do nothing more than setting the http method, the "email-templates" path and the body (if applies). But I haven't seen the rest of the library, so can't compare. Anyway:

  • I'd add in the "javadocs" the required scope to call that method. i.e. create:email-templates. You can get those from the api explorer docs.
  • Some methods require at least some parameters to be passed. i.e. for creating a new template you need to provide a name, for sure. Maybe it's worth to validate those cases locally before wasting time (and resources) in making a request we already know is going to fail.
  • Template names are limited to a few options. Maybe it's worth to provide some constants so users find easier to type them or add some local name validation?

$builder->withHeaders($this->headers);

if ( in_array( $method, [ 'patch', 'post', 'put' ] ) ) {
$builder->withHeader( new ContentType('application/json') );
Copy link
Contributor

Choose a reason for hiding this comment

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

I know this works for when you need to send a body in the request, but probably would be good to check if all requests send the Accept header so the server knows what you're expecting back in the response.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't see an Accept header used in any of the examples in the docs. I'm wary of just dropping that in if it's not documented.

*
* @return array
*
* @throws \Exception - if a 200 response was not returned from the API.
Copy link
Contributor

Choose a reason for hiding this comment

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

Be carefull. Some endpoints return success codes different to 200, i.e. create connection:

image

While this doesn't apply to email-templates, might be worth to check the rest of the entities if this was a copy-paste of that logic/javadocs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I checked before submitting, all are 200 but good eyes 👍

const EMAIL_TEMPLATE_NAME = 'enrollment_email';

/**
* Management API token with scopes read:email_templates, create:email_templates, update:email_templates
Copy link
Contributor

Choose a reason for hiding this comment

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

while this is true for calling all endpoints, some of them can be called with only 1 of this scopes. So this is not exactly true

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is in a test and for the tests here to run, it needs all three.

@joshcanhelp
Copy link
Contributor Author

Thanks @lbalmaceda ... this is definitely more documentation than the other methods have but I'm trying to use it as a good template to go back through the others and fill it all out. Your suggestions are 👍

@joshcanhelp
Copy link
Contributor Author

@lbalmaceda - Responses to your comment:

  • "required scope" - good call, added
  • "Some methods require at least some parameters ... validate those cases locally" - I thought about this and was on the fence. You'll always need a template name, sure, but everything else is subject to change, new fields to be added, etc. I can see the utility in checking for required fields now but that's more to update ... and frustrate developers down the road. I added a more clear comment on this but happy to keep talking about how this should be handled.
  • "Template names are limited" - Same general feelings as the above. I started to go down that route and thought that new templates would be a very likely scenario and if we're only whitelisting certain ones then we'd have to stay on top of additions there and add them quickly or someone is going to get a confusing kick-back from the SDK.

@joshcanhelp joshcanhelp force-pushed the add-email-template-endpoints branch from a314710 to a0bf285 Compare April 24, 2018 22:35
@lbalmaceda
Copy link
Contributor

About local validation:

  • to create a new email-template you require all this properties at least: "template", "body", "from", "subject", "syntax", "enabled", the rest are optional.
  • to get/patch an existing email-template you require the "templateName".

About template names, the alternative I proposed (even on my PR) is to pre-define a set of constants that users can use to easily type a template's name. i.e. const TEMPLATE_ENROLL = "enrollment_email"

@joshcanhelp
Copy link
Contributor Author

to create a new email-template you require all this properties at least: "template", "body", "from", "subject", "syntax", "enabled", the rest are optional.

For now but one could be added later and now the SDK is out of date. I'm just thinking about that as a pattern for the rest of the SDK. We're duplicating the validation that's happening on the server to save a handful of API calls at the cost of a lot of up-front and maintenance work.

$0.02

to get/patch an existing email-template you require the "templateName".

Correct, those are already there. I could require a template name for create but then the rest of the fields are required as well.

@joshcanhelp joshcanhelp force-pushed the add-email-template-endpoints branch from a0bf285 to 3e612ad Compare April 25, 2018 14:38
@lbalmaceda
Copy link
Contributor

but one could be added later and now the SDK is out of date

False! If the server adds a new required parameter, the validation that now fails is the remote one and not the local. Yes, SDK is out of date and will need to be updated if you want the validation to detect that locally first. But that's not stopping people from calling this method. TBH I find this really useful! Otherwise every API/Entity would rely on a single generic class that receives a) the method, b) the path and c) the data/body. What's the point on having separate classes for them then? Would like to hear from someone else too (@cocojoe?).

Correct, those are already there.

But they are not being null-checked. Would it be fine if the request fires with a null template name?

@@ -30,7 +30,7 @@
}
},
"scripts": {
"test": "vendor/bin/phpunit",
"test": "SHELL_INTERACTIVE=1 vendor/bin/phpunit --colors=always --verbose ",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Allows for additional data after the command (like path to a specific test) and makes the output a little more useful

* @param array $data
* An array of data to use for the new email, including a valid `template`.
* See docs link below for required fields.
* @param string $template - the template name to create
Copy link
Contributor

@lbalmaceda lbalmaceda May 3, 2018

Choose a reason for hiding this comment

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

I'd add "You can add any of the constants defined in this file" or something like that.. suggesting the users an easy way to access those values.. BTW this applies to all methods on this entity

$data = [
'template' => (string) $template,
'from' => (string) $from,
'body' => (string) $body,
Copy link
Contributor

Choose a reason for hiding this comment

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

How does validation work here? And what happens since some of the params have a default value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Anything with a default value is not required by the API, only template and from. The object you POST needs to have those keys but they can be empty.

$template and $from are both required for the method (IOW: need to have something passed in) but nothing beyond that. Looking through the rest of the SDK, this is how validation is handled for other endpoints. I could check for empty() but it's a bit of an edge case if someone sees that the param is required but passes in an empty string or null or something.

If it was empty, I'd have to throw and exception of some kind. Since this is a new method, I could do that even though none of the other ones do and make that a pattern to follow. If that template is empty, the HTTP client would throw an exception anyways so not a complete surprise.

I'm happy with this as-is but also open to more discussion.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm looking at the schema definition right now.. You shouldn't be setting values in the SDK if they are missing just because "need to have something passed in". Of course you'll need to pass something, that's why it's required. But let it fail gracefully! If the parameters are required, make the user manually set them, even if they want to set an empty string. The only exception I find for this is the syntax field which is there for backwards (read) compatibility and liquid should be used always as value when creating new templates.

Think of receiving an email in your personal inbox which doesn't have a subject set or which doesn't have a body at all. Would that make sense to you as a user of that Application? Don't you want to make sure that users of this SDK use the API well?

@joshcanhelp joshcanhelp force-pushed the add-email-template-endpoints branch 2 times, most recently from 9310228 to b4d17c4 Compare May 4, 2018 21:04
Copy link
Contributor

@lbalmaceda lbalmaceda left a comment

Choose a reason for hiding this comment

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

LGTM

@joshcanhelp joshcanhelp force-pushed the add-email-template-endpoints branch from 5749cc1 to fac955b Compare May 8, 2018 14:41
@joshcanhelp joshcanhelp force-pushed the add-email-template-endpoints branch from 84df7f1 to fefdf6e Compare May 8, 2018 14:55
@joshcanhelp joshcanhelp merged commit a068135 into master May 8, 2018
@joshcanhelp joshcanhelp deleted the add-email-template-endpoints branch May 8, 2018 16:00
@github-actions
Copy link
Contributor

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants