Add Go and Terraform code samples to the API specs - #55
Merged
Conversation
Extends the sample conventions in CLAUDE.md with the two new tabs (Go as entry 8, OpenTofu as entry 9) and applies them to the smallest spec as a render canary: 5 Go samples and 4 OpenTofu ones. lang: hcl with label: OpenTofu, because GitBook highlights with Prism, which has an hcl component and no terraform one. Unsupported operations get no entry at all rather than a limitation comment, so the templates list operation has no OpenTofu tab (the provider has no list data source). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
32 samples: all 30 operations in sandbox.openapi.yml plus the two sandbox-sending ones. The sandbox sending client is constructed with WithSandbox(true) and WithSandboxID(...), which is what routes Send and SendBatch to the sandbox host. The five body.* operations return raw bytes, so those samples print string(body). The message list sample also shows the SandboxMessages.All iterator, which is the idiomatic way to walk every page. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
28 samples: 24 of the 27 operations in email-sending.openapi.yml, plus the two bulk and two transactional sending operations. Host selection is a client option, so the bulk samples construct the client with WithBulk(true) and the transactional ones use the default. The three tracking opt-out operations get no Go sample: the SDK has no support for them, and an absent tab is better than one that says so. Go lands on five operations the other SDKs still skip (updateDomain, the three company_info operations, and createSuppression), so those tabs will show cURL, Ruby and Go only until the other languages are back-filled. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
32 samples covering all 19 contacts operations and all 13 account-management ones. Contact identifiers are a UUID or an email address, and the contact update endpoint is an upsert, so that sample prints the action the API reports. The two sub-account samples construct the client with WithOrganizationID, which those endpoints require. The API token samples do not set an expiration, so they match what the API applies by default. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
30 samples across sandbox, contacts, email-sending and account-management, completing the provider's coverage at 34 of the 130 documented operations. A resource block is not an API call, so every sample opens with a comment naming the lifecycle command that fires the endpoint, and each sample is self-contained down to the required_providers block. Where the provider has a data source (project, sandbox, domain, account) the read samples use it; the rest pair the resource block with a tofu import line. Attribute names come from the provider schema rather than its published examples, so the resource is mailtrap_domain and every email_sending webhook sets sending_stream. The samples also carry the provider's real footguns as comments: the API token has no update path, an imported token or webhook has no secret, and a template body cannot be cleared. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
11 samples, one per campaign operation, covering the draft/schedule/start lifecycle and the stats endpoint. The update sample shows the pointer-to-slice fields: nil leaves the contact lists and segments unchanged, while a pointer to an empty slice clears them. The list sample also shows the EmailCampaigns.All iterator. Deliberately the last commit on this branch: PR #54 is adding the six other languages to these same x-codeSamples lists, so this commit is the one to rebase or drop once #54 lands. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Rabsztok
marked this pull request as ready for review
September 1, 2026 10:19
The provider is `terraform-provider-mailtrap` and ships to both registries; Terraform is the name readers of the docs dropdown will recognise. - `label: OpenTofu` -> `label: Terraform` on all 34 hcl samples (`lang: hcl` is unchanged - Prism still has no `terraform` component). - Lifecycle comments now name the terraform CLI: `terraform apply/plan/ import/destroy`. The commands are interchangeable, so the configs are unaffected. - CLAUDE.md conventions updated to match, so future samples are added as Terraform. Re-verified: Spectral clean, and all 34 samples extracted back out of the committed YAML are `terraform fmt -check` clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mklocek
reviewed
Sep 3, 2026
IgorDobryn
approved these changes
Sep 3, 2026
IgorDobryn
left a comment
Contributor
There was a problem hiding this comment.
Not sure how to document terraform for import/delete/update operations
All six SDKs now live under github.com/mailtrap; .NET and Java were still listed as future references.
Update, delete and import are native resource lifecycle and are documented once by the provider, so a per-endpoint sample repeats the resource block without adding anything. Drop those 20 samples, keep the 8 creates and the 6 reads that map to a real data source, and point the create samples at the provider docs on the Terraform registry (review feedback on #55).
mklocek
approved these changes
Sep 4, 2026
Rabsztok
added a commit
that referenced
this pull request
Sep 4, 2026
main added Go samples to the email campaigns endpoints (PR #55) while this branch was adding the Node.js, PHP, Python, Ruby, .NET and Java samples, so every one of the 11 x-codeSamples lists in specs/email-campaigns.openapi.yml conflicted as an append-vs-append. Resolved by keeping both sides in every list. Concatenating this branch's languages before main's Go sample happens to land on the priority order CLAUDE.md documents: cURL, Node.js, PHP, Python, Ruby, .NET, Java, Go. The one place the two sides genuinely overlapped is the schedule endpoint's cURL sample: main still carried the hardcoded "2026-06-01T09:00:00.000Z" payload that this branch had already replaced with a computed $DATETIME (dafe709, 294867a) precisely because the literal had gone stale and returned 422. This branch's version supersedes it, so main's line is dropped rather than duplicated. Same reasoning for the Schedule schema example, which auto-merged to this branch's 2026-10-01 literal. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
MT-23475 — the API docs dropdown offers
seven tabs (cURL plus six SDKs), but two shipping tools are missing from it entirely: the
Go SDK (
mailtrap/mailtrap-go) and the Terraform provider(
mailtrap/terraform-provider-mailtrap). The dropdown is driven purely by each operation'sx-codeSampleslist, so adding a tab means adding an entry.The ticket AC scopes this to "every supported endpoint", which is what keeps this at 142
samples rather than 260: no sample is written against a method, attribute or resource that
does not exist.
Changes
3,659 insertions, 5 deletions (the five are the
CLAUDE.mdSDK repository lines moved to themailtraporg). No existing sample, description, base URL or operation order changes.CLAUDE.md: Go as sample entry 8 and Terraform as entry 9, plus the conventions for both(why
lang: hcl, the leading lifecycle comment, the verification commands, and the rulethat an unsupported operation gets no entry rather than a "not supported" comment).
14 Terraform (11%).
sandbox.openapi.ymlemail-sending.openapi.ymlcontacts.openapi.ymlinbound.openapi.ymlaccount-management.openapi.ymlemail-campaigns.openapi.ymltemplates.openapi.ymlemail-sending-transactional.openapi.ymlemail-sending-bulk.openapi.ymlsandbox-sending.openapi.ymlNever covered, deliberately: all 19
inboundoperations (the SDK has no inbound support,and the provider has no inbound resources) and the 3
tracking_opt_outsoperations. Those keepthe samples they have. A provider is declarative, so it covers no sending, no campaigns, no
message inspection, and manages contact lists and fields but never contact data. Terraform samples cover only creates
(8
resourceblocks) and reads backed by a real data source (6datablocks); update, delete andimport are native resource lifecycle documented once by the provider, so those operations get no
Terraform tab (review feedback).
Conventions
package mainprograms. That is not decoration — it is what makesthem compile-checkable, which is the whole quality argument here. Token from
os.Getenv("MAILTRAP_API_TOKEN")(the idiom in all of the SDK's own examples; note it divergesfrom the sibling tabs' literal
YOUR_API_KEY),context.Background()inline, responsediscarded as
_,log.Fatalon error,mailtrap.Ptrfor optional pointer fields, exportedconstants over string literals. Written against v0.3.0, the latest release, so
go getgives a reader exactly what the sample compiles against.
lang: hclwithlabel: Terraform. GitBook highlights with Prism,which has an
hclcomponent and noterraformone;langresolves through Prism identifiersrather than GitBook's documented linguist list, as the existing
csharpandshellsamplesalready demonstrate. The tab is titled by
label, so it reads "Terraform" regardless.An HCL block is not an API call, so every sample opens with a comment naming the lifecycle
command that fires the endpoint (
# terraform apply creates the domain: POST /api/domains); createsamples add a second comment linking the provider docs on the registry,
where the lifecycle operations live. Each sample is self-contained down to
required_providers—that tab is where a reader learns the source string.
in two places: the resource is
mailtrap_domain(renamed frommailtrap_sending_domain), andevery
email_sendingwebhook sets thesending_streamthe API requires. The samples alsocarry the provider's real footguns as comments (no update path on
mailtrap_api_token, nosecret after an import, a template body that cannot be cleared).
Merge order — two preconditions
campaigns-sdk-samples) should merge first. It adds the six other languages to thevery same 11
x-codeSampleslists inemail-campaigns.openapi.yml. Once it lands, thisbranch rebases onto it and the last commit (
8667411) is the only one that needs resolving —or it can be dropped and redone. Nothing on Add SDK code samples to email campaigns endpoints #54's branch was touched.
Terraform samples are written against the real published form (
source = "mailtrap/mailtrap"in a plain
required_providersblock) with nodev_overridesworkaround and no "not yetpublished" caveat, on the understanding that
mailtrap/terraform-provider-mailtrapispublished ahead of this. Merging before that ships a config that does not
terraform init.How to test
CI runs Spectral, which is the only automated gate in this repo. The other two checks are local
and are the ones that catch real bugs, so they were run on the samples extracted back out of
the committed YAML, not on drafts.
npx -y @stoplight/spectral-cli lint "specs/*.openapi.yml" --verbose→ "No results with a severity of 'error' found!"
lang: gosample extracted to its own package againstgithub.com/mailtrap/mailtrap-go@v0.3.0: 108 packages,gofmt -lempty,go vet ./...clean,
go build ./...clean. This caught a real defect — an email-logs filter operatorof
eqwhere the API takesequal.lang: hclsample extracted to its ownconfig: 34 configs at the time (the 14 kept are a subset; the later cut only added a comment line),
fmt -check -diffclean, andvalidateagainst a provider binarybuilt from
terraform-provider-mailtrap'sorigin/mainunderdev_overrides— the onlymechanical check on attribute names. All 34 validate. (
validatewas originally run withthe OpenTofu CLI; the two CLIs are drop-in for
fmt/validatehere, and the labelrename touched only comments, so
terraform fmt -checkwas re-run on all 34 after it.)gofmttabs live insidesource: |block scalars. Tabs are legal in block-scalar content; the round-trip through
extract →
gofmt -lis the proof.gois always the second-to-last entry whenhclfollows,hclis always last, no duplicate langs.docs.mailtrap.io/developersand confirm the dropdown reads cURL, Node.js, PHP, Python, Ruby, .NET, Java, Go,
Terraform, that Go is highlighted, and that Terraform renders. If
hclturns outunhighlighted the tab still appears — accept that rather than switching to
lang: terraform, which Prism does not know either.Images
Worth a reviewer's eye
updateDomain, the threecompany_infooperations, andcreateSuppressioncurrently have onlyshell(+ruby).Those tabs will read cURL / Ruby / Go until the other five languages are back-filled, which
deserves its own ticket.
MAILTRAP_API_TOKENfrom the environment; the sibling tabsuse a literal
YOUR_API_KEY. That follows the SDK's house style andCLAUDE.md's"use environment variables for API keys", but it is a visible inconsistency inside one
dropdown and a one-line-per-sample change if you would rather it matched.
required_providersboilerplate. Thealternative is the provider docs page, which the create samples now link to.
import-style reads are gone; only creates and genuine data-source reads remain.