<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Transposit</title>
    <description>The latest articles on DEV Community by Transposit (@transposit).</description>
    <link>https://dev.to/transposit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F143179%2F59ccb62e-160b-4193-bdc6-8febc3796755.jpg</url>
      <title>DEV Community: Transposit</title>
      <link>https://dev.to/transposit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/transposit"/>
    <language>en</language>
    <item>
      <title>Embracing the SaaS unbundleverse</title>
      <dc:creator>Transposit</dc:creator>
      <pubDate>Wed, 15 May 2019 20:56:21 +0000</pubDate>
      <link>https://dev.to/transposit/embracing-the-saas-unbundleverse-1lp1</link>
      <guid>https://dev.to/transposit/embracing-the-saas-unbundleverse-1lp1</guid>
      <description>&lt;p&gt;Written by Adam Leventhal&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KO4h-Me8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ADMY1uc3rDbEWRZzAPUnXAw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KO4h-Me8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ADMY1uc3rDbEWRZzAPUnXAw.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Previous eras of software consumption were defined by their bundles. Our current era is defined by its diverse application ecosystem, its unbundling. Even recently, corporate consumers wore their fealty to a vendor with pride: we’re a Microsoft shop, we’re an Oracle shop, we’re an IBM shop. While devoted, the relationship wasn’t monogamous. The right tool for the job, but guided by relationship as the north star. Bundling had the benefit (at least perceived) of interoperability — many tools, intermeshed, helping us work well as a team.&lt;/p&gt;

&lt;p&gt;SaaS changed both the economics of software, and the adhesion of the bundle. Even if you wanted to be a mono-shop, it’s harder to see how to do that (or why you’d want to). Teams are picking the tools they want. Applications are able to be deeper and narrower than ever before. Consequently everyone has many more applications from a much more distributed collection of vendors.&lt;/p&gt;

&lt;p&gt;Established and new companies are repositioning for this distributed, diverse unbundleverse. We started Transposit to help build the apps composed of the APIs from unbundled software. We’re betting on this trend. But I heard a new vision for this modern era of software a couple of weeks ago at Slack’s Frontiers conference: that there can be hubs even amid unbundling, centers in an era of decentralization. Rather than grouping like-applications, these hubs group like-activities. In an unbundled world, the monopolies will be horizontal, aggregating similar kinds of interactions across applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Slack on Slack
&lt;/h3&gt;

&lt;p&gt;At the conference, Slack laid out a significant and compelling vision about becoming a major epicenter amid this sectoral unbundling. While the conference felt bold and enlightening, Slack’s summary blog post was more pedestrian: mostly new features and non-specific enthusiasm. It listed shared channels, Workflow Builder, and Gmail/Outlook gateways as some big pieces. Under the heading “Building the tools for modern work”, the video featuring CPO, Tamar Yehoshua, touches on a common theme of the conference:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“But communication at work doesn’t just happen between people. We need access to data and other workflows. A typical enterprise uses more than 1000 cloud applications. These software tools fragment attention and make it harder for information to flow across an organization. So we want to do more and more to connect Slack to the critical tools behind every business.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  1071
&lt;/h3&gt;

&lt;p&gt;To anyone at Frontiers, the number 1071 will feel at least familiarly significant. I counted it in no fewer than 6 different talks by various members of the Slack ensemble. It’s the average number of cloud applications in an enterprise. (Apparently from &lt;a href="http://go.netskope.com/rs/665-KFP-612/images/april-2017-worldwide-cloud-report.pdf"&gt;this Netskope report&lt;/a&gt;.) This was the strong theme of the conference: companies have tons of SaaS applications and Slack is the hub for collaboration, approvals, workflows, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j_C7Kki9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/594/1%2AQ5lqxw6E-3OmFUE1bZ1mMQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j_C7Kki9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/594/1%2AQ5lqxw6E-3OmFUE1bZ1mMQ.png" alt=""&gt;&lt;/a&gt;Not sure which session; could have been any of them.&lt;/p&gt;

&lt;p&gt;As an aside, Slack’s famously humble, empathetic culture was also on display. The second most common theme was speakers thanking the audience for laughing — just take your yuks and move on folks! (And &lt;a href="https://dev.to/realtransposit/hypebot-is-the-hype-man-who-never-lets-me-down-5bfm"&gt;we have the perfect hype man&lt;/a&gt;!)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S9hhq886--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A9pgjmBHTvDL_a645RxZgIA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S9hhq886--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A9pgjmBHTvDL_a645RxZgIA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tUSduEsc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AH0IJBcXzTlukGfOXfT6jFQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tUSduEsc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AH0IJBcXzTlukGfOXfT6jFQ.png" alt=""&gt;&lt;/a&gt;You’re welcome.&lt;/p&gt;

&lt;p&gt;Apps form silos. Silos impede cross-team communication and collaboration. If a task needs approvals from a bunch of folks in a bunch of tools, it’s going to be faster if it happens in Slack. If people use tools infrequently, offer common tasks through Slack. And rather than gathering data from multiple apps, bring it all together in the tool everyone’s already got open, Slack. It’s the aspiring epicenter of work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hub at the center of the unbundleverse
&lt;/h3&gt;

&lt;p&gt;SaaS has fractured the traditional bundles. The new monopoly opportunity is horizontal. Rather than taking over collections of applications, these hubs will own common tasks across the landscape of apps. Slack wants to own collaboration and lightweight interactions across apps. It’s a monopoly that embraces a sprawling ecosystem rather than trying to own it. These catalyze expansion and heterogeneity where bundles sought to contain it. Every major software vendor is looking for their hub opportunity.&lt;/p&gt;

&lt;p&gt;How will Slack become this hub? How will anyone? In their S-1 (published the day after Frontiers), Slack cited several components of their growth strategy. The first 6 are different aspects of sales and marketing. The 7th addresses their platform vision (and could be copied almost verbatim from other aspiring hubs):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Grow our application platform and developer ecosystem&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
We will continue investing to expand the number of developers building applications that integrate with Slack and to make Slack work with an increasing number of third-party and internally developed custom applications.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(The 8th and final growth strategy is “Leverage artificial intelligence, machine learning and advanced search”, a shibboleth of our times I suppose.)&lt;/p&gt;

&lt;p&gt;For any hub, there’s the core platform, the surround of apps and APIs, and a yawning gap in between. Platforms and users alike are dependent on developers to fill that divide, to write the software that wires together hub and edge. From Zapier, to Airtable, and Transposit, that’s why we’re here. As much as the hubs will define our future so will the developers, tools, and platforms that bind it all together.&lt;/p&gt;

&lt;p&gt;—&lt;/p&gt;

&lt;p&gt;Building Slack bots or other connections between hub and edge? &lt;a href="https://www.transposit.com/?c=hub_medium_post"&gt;Try Transposit&lt;/a&gt;.&lt;/p&gt;




</description>
      <category>slack</category>
      <category>softwaredevelopment</category>
      <category>enterprisetechnolog</category>
      <category>api</category>
    </item>
    <item>
      <title>Superglue for Gaps in Your AWS Infrastructure — automation scripts using SQL and Javascript</title>
      <dc:creator>Transposit</dc:creator>
      <pubDate>Tue, 07 May 2019 21:50:36 +0000</pubDate>
      <link>https://dev.to/transposit/superglue-for-gaps-in-your-aws-infrastructure-automation-scripts-using-sql-and-javascript-5fjd</link>
      <guid>https://dev.to/transposit/superglue-for-gaps-in-your-aws-infrastructure-automation-scripts-using-sql-and-javascript-5fjd</guid>
      <description>&lt;p&gt;Written by Yoko Li&lt;/p&gt;

&lt;h3&gt;
  
  
  Superglue for gaps in your AWS infrastructure — automation scripts using SQL and Javascript
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H5u03XBY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AwrXQwegZmzM2N9BhkT9i8g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H5u03XBY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AwrXQwegZmzM2N9BhkT9i8g.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Introduction
&lt;/h4&gt;

&lt;p&gt;I’m a big fan of AWS, but I wish there was a bit more “glue” within the AWS system itself, and between AWS and services like Slack and GitHub. An example of the sort of glue I’m looking for: a mechanism for defining a more complex lifecycle policy, where I could write some code to control resources I want to delete on AWS.&lt;/p&gt;

&lt;p&gt;To solve this problem, we built a Transposit app that purges unused resources on ECR and ECS and then posts the results on Slack so the whole team gets notified. This enabled us to ditch the lambda function we built previously that was hard to debug and iterate on.&lt;/p&gt;

&lt;p&gt;Before diving in, a little background. Our deployment works like this: on every build success we deploy to our test environment, under the hood these things happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a new image based on latest code, and put that image in ECR&lt;/li&gt;
&lt;li&gt;Create a new task in ECS, and tell the task to use the image we just created&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem with this system is that because each build creates ECR images and ECS tasks, and both ECR and ECS provide limited amount of storage, we eventually need to clean up old resources so our build doesn’t fail from running out of space.&lt;/p&gt;

&lt;h4&gt;
  
  
  The old world with Lambda
&lt;/h4&gt;

&lt;p&gt;To clean up old tasks and images, our earlier solution was to write a lambda function. A lambda function let us have custom logic to check what’s currently in use by ECS tasks and delete images and tasks not in use. A problem arose when the function failed without us knowing; we hadn’t built in active notifications so didn’t realize it failed. This led to unused resources piling up, and one day, caused our build to fail. The build kept failing until we freed up some space in ECR.&lt;/p&gt;

&lt;p&gt;Not only was it failing, but it actually didn’t do everything we wanted: it didn’t account for inter-account dependencies on our ECR repositories and was deleting more images than it should. Besides, based on the failures above, it would be nice to have notifications!&lt;/p&gt;

&lt;p&gt;In our lambda, the code to figure out which images are in use is complicated. It needs to use a pagination token to get a full list of ECS tasks, iterate through them, and find out what tasks and images are both old and not currently in use. It’s a pain to have to do that pagination by hand and look up how to use each AWS API. I won’t bore you with the details of how it works, but you can click through the screenshots if you want to see all the code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z5fIQt6O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Af6Qft2O8eyG0M3Oi9nvhAA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z5fIQt6O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Af6Qft2O8eyG0M3Oi9nvhAA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pknafBti--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ADCMRvfwdQlyqk1ziLlRaKw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pknafBti--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ADCMRvfwdQlyqk1ziLlRaKw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1Ig99yAz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A1U_GepZhIJUeyjRnceB-eg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1Ig99yAz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A1U_GepZhIJUeyjRnceB-eg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rather than investing more into this complex lambda function, we rebuilt the functionality in a Transposit app. Based on what we learned from building on lambda, we built an app called &lt;strong&gt;cleanup_task&lt;/strong&gt; using SQL and Javascript on Transposit.&lt;/p&gt;

&lt;h4&gt;
  
  
  The new world with Transposit
&lt;/h4&gt;

&lt;p&gt;To make sure we don’t delete any image in use, we have to first find out which images are currently being used. Here is how I built it in Transposit:&lt;/p&gt;

&lt;p&gt;The code below gets all the ECS tasks that are currently in use by iterating through all active services within our cluster and looking at task definitions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nk81o17q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A4vg2MLX6ofRUSy-UeIsUvw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nk81o17q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A4vg2MLX6ofRUSy-UeIsUvw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can then use the above operation (which we call &lt;strong&gt;get_tasks_in_use&lt;/strong&gt; ) to get the images that those ECS tasks are attached to.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4CPaPSY3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AWfurYz8tFPU3BLmpxv7cFw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4CPaPSY3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AWfurYz8tFPU3BLmpxv7cFw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we have all the images we want to keep, we iterate through all the images in an ECR repository, and delete the ones that are both old and no longer in use. We call GitHub to verify image commit time, since each image was built from a single commit:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DUnNQwpW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AFaejR2Yd_jWJECrU9gz7Og.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DUnNQwpW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AFaejR2Yd_jWJECrU9gz7Og.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Get notified!
&lt;/h4&gt;

&lt;p&gt;I mentioned earlier that it would be helpful to build Slack notification on top of this project, which posts to a Slack channel about what has been done to AWS resources. Trying to build this into a lambda function is a struggle: I would need to setup OAuth from scratch and figure out how to use Slack APIs. With Transposit, I was able to build this with very little code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J9_HQVAQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AQ6KXNwC3Hmy37Kl9Q-lHKg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J9_HQVAQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AQ6KXNwC3Hmy37Kl9Q-lHKg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NbiTFLkg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/671/1%2AjPLNNv45WbQ5VeHsk9DBpg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NbiTFLkg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/671/1%2AjPLNNv45WbQ5VeHsk9DBpg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The output is kind of raw, but it tells me what I need to know. When it fails, it also tells me that.&lt;/p&gt;

&lt;p&gt;With our old lambda I would lose sleep worrying about whether our build would fail. I’d obsessively check out Cloudwatch logs to make sure nothing had gone wrong. The new Transposit version is easier to understand, easier to write, easier to extend, and tells me when things fail. I still get the benefits of using scheduled tasks to run it and not needing to worry about the underlying infrastructure. I now have the confidence that if something fails I’ll be able to address it before it becomes a problem. Each new feature — Slack notifications, GitHub integration, event queuing through AWS Dynamo — has become much quicker to add.&lt;/p&gt;

&lt;p&gt;You can fork the full version of this app &lt;a href="https://console.transposit.com/t/transposit-sample/aws_ecs_ecr_cleanup/code/op/delete_old_tasks_dryrun?c=cleanup_task_medium_post"&gt;here&lt;/a&gt; if you want to see how it works and try it out against your own infrastructure. We also made a sample app for purging objects stored in S3, which you can find &lt;a href="https://console.transposit.com/t/transposit-sample/cleanup_aws_s3/code/op/delete_dryrun?c=cleanup_task_medium_post"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the next bit of glue you need to hold your AWS infrastructure together, try out Transposit.&lt;/p&gt;

&lt;p&gt;Sign up for Transposit here&lt;/p&gt;




</description>
      <category>devops</category>
      <category>lambda</category>
      <category>sql</category>
      <category>aws</category>
    </item>
    <item>
      <title>Google Hire Has An API. Finally.</title>
      <dc:creator>Transposit</dc:creator>
      <pubDate>Fri, 12 Apr 2019 15:46:00 +0000</pubDate>
      <link>https://dev.to/transposit/google-hire-has-an-api-finally-2g4e</link>
      <guid>https://dev.to/transposit/google-hire-has-an-api-finally-2g4e</guid>
      <description>&lt;p&gt;Written by Adam Leventhal&lt;/p&gt;

&lt;p&gt;We had just convinced our Seed round investors that Transposit was a big idea. A big idea needs a team to build it, so when the first round closed we started hiring that team. We’d talk to candidates and write down our feedback to share with the team. At first we used Google Docs. The price was right (free), but we quickly outgrew it: we needed more structure and access control. My experience with application tracking systems (ATS) is that they’re all infuriating in their own way, imposing their structure on your process rather than adapting to it. So if we weren’t going to get what we wanted, at least we didn’t want to pay a lot for it.&lt;/p&gt;

&lt;p&gt;Enter Google Hire.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F708%2F0%2AjYqchS6RTEicPQEa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F708%2F0%2AjYqchS6RTEicPQEa.jpg"&gt;&lt;/a&gt;Hell is other people… trapping your data with no API&lt;/p&gt;

&lt;p&gt;As anticipated, Google Hire wasn’t exactly what we wanted. What it was though was cheap. It’s not a terrible product; it just doesn’t do anything quite the way we’d like. Filter by recruiter, handoff candidate ownership, find folks we haven’t pinged in awhile — Hire didn’t do any of those things.&lt;/p&gt;

&lt;p&gt;No problem, right? That’s what APIs are for. Your service might not suit my needs, but an API lets me work around the parts I hate and build the extensions I need. Even if the product improved to meet our needs, there would always be a next need. But — amazingly for a Google product[1] — there was no API.&lt;/p&gt;

&lt;p&gt;So we suffered. And in the meantime we hired our team and &lt;a href="https://www.transposit.com" rel="noopener noreferrer"&gt;built our product&lt;/a&gt; that — with some irony — made it easy to work with APIs. By a happy coincidence, Google Hire released their &lt;a href="https://developers.google.com/hire/tenants/guides/getting-started" rel="noopener noreferrer"&gt;beta API&lt;/a&gt; right around the time Transposit opened our beta. Transposit puts a SQL and JS interface in front of APIs, manages auth, and makes it easy to build API-driven APIs. Here are the first couple of queries I ran against the Google Hire API. (You can &lt;a href="https://console.transposit.com/t/ahl/hire" rel="noopener noreferrer"&gt;try everything out live&lt;/a&gt; once Google gives you API access.)&lt;/p&gt;

&lt;p&gt;I can list all the candidates we’re tracking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT \* FROM google\_hire.list\_candidates
  WHERE tenant=‘my\_tenant’
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can see the past employers of all the folks we’re talking to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT employmentInfo.employer FROM google\_hire.list\_candidates
  WHERE tenant=’my\_tenant’ EXPAND BY employmentInfo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Amusingly in the context of this post, the top hit is Google)&lt;/p&gt;

&lt;h3&gt;
  
  
  Solving problems
&lt;/h3&gt;

&lt;p&gt;After being held at arm’s length for far too long, I had a lot of fun exploring the newly public(-ish[2]) API. The first real problem I wanted to solve was to show the candidates whom we haven’t pinged recently. Why is this not built in? I have no idea. It was easy enough to get to with Transposit. We treat each API like a view or table within a database; getting the data I wanted amounted to a JOIN between the candidates and applications tables:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/media/0103d33ee62c48d82b569ab9af8c2747/href" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://medium.com/media/0103d33ee62c48d82b569ab9af8c2747/href" rel="noopener noreferrer"&gt;https://medium.com/media/0103d33ee62c48d82b569ab9af8c2747/href&lt;/a&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "name": "tenants/abc/candidates/def",
    "job": "tenants/acb/jobs/ghi",
    "candidate": "tenants/abc/candidates/jkl",
    "createTime": "2019-04-02T00:31:48.630Z",
    "status": {
      "state": "ACTIVE",
      "processStage": {
        "stage": "Initial Screen",
        "reportingCategory": "SCREEN"
      },
      "updateTime": "2019-04-03T05:27:29.321Z"
    },
    "personName": {
      "givenName": "David",
      "familyName": "Lightman"
    },
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can focus that in on a particular job by adding another SQL filter:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/media/1f3bac392e9c743010c9b25872a34158/href" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://medium.com/media/1f3bac392e9c743010c9b25872a34158/href" rel="noopener noreferrer"&gt;https://medium.com/media/1f3bac392e9c743010c9b25872a34158/href&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;… and then get the data I want by plucking out particular fields and adding an ORDER BY:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/media/1b85f16bf4ff02fa2f40b489465d7810/href" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://medium.com/media/1b85f16bf4ff02fa2f40b489465d7810/href" rel="noopener noreferrer"&gt;https://medium.com/media/1b85f16bf4ff02fa2f40b489465d7810/href&lt;/a&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    "updateTime": "2019-03-12T17:25:33.176Z",
    "givenName": "Michael",
    "familyName": "Jennings"
  },
  {
    "updateTime": "2019-03-21T20:33:08.454Z",
    "givenName": "Kate",
    "familyName": "Libby"
  },
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally! The data I’ve wanted since we first started using Hire!&lt;/p&gt;

&lt;h3&gt;
  
  
  All Hail Our Benevolent Slack Overlords
&lt;/h3&gt;

&lt;p&gt;Slack is rapidly becoming the central interface across so many tools we use, so I wanted the data from Google Hire connected up with Slack. Building a Slack slash command is a snap (&lt;a href="https://docs.transposit.com/get-started/quickstart" rel="noopener noreferrer"&gt;check out the Transposit Quickstart&lt;/a&gt;). You just need to point Slack at a webhook that returns the data you want:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/media/5aed6a0835a234647aaba99de0820df2/href" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://medium.com/media/5aed6a0835a234647aaba99de0820df2/href" rel="noopener noreferrer"&gt;https://medium.com/media/5aed6a0835a234647aaba99de0820df2/href&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now when I worry if we’ve dropped the ball on a candidate and they haven’t heard from us in a while, I can just type my Slack slash command:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F656%2F1%2Aql4TpGbGHUYKdgE_pkJH5w.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F656%2F1%2Aql4TpGbGHUYKdgE_pkJH5w.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Next
&lt;/h3&gt;

&lt;p&gt;As excited as I was for the Google Hire API, the endpoints in the first beta are pretty basic. It will be extremely powerful when they open up the ability to do things like create new candidates, transition candidates between stages of the hiring process, and add comments (the mechanism we use to hand off candidates between members of our team).&lt;/p&gt;

&lt;p&gt;An API is a critical feature of any tool we use; &lt;strong&gt;I’ll never again make the mistake of choosing a tool that doesn’t give me access to my data via an API&lt;/strong&gt;. Transposit let me explore the Google Hire API interactively, check out the data, and poke around at different endpoints. You can &lt;a href="http://www.transposit.com" rel="noopener noreferrer"&gt;try it out&lt;/a&gt; with the Hire API or any of the other APIs it connects to. And if this sounds like something you’d like to get involved in, &lt;a href="https://www.transposit.com/jobs/" rel="noopener noreferrer"&gt;we’re hiring&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT title FROM google\_hire.list\_jobs
 WHERE tenant=’my\_tenant’
 AND filter=’state=OPEN’

[
  {
    "title": "Developer Advocate"
  },
  {
    "title": "Growth Marketing Manager"
  },
  {
    "title": "Product Marketing Manager"
  },
  {
    "title": "Senior Site Reliability Engineer"
  },
  {
    "title": "Software Engineer"
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[1] I call it a Google Product — and I knew this beforehand — but &lt;a href="https://venturebeat.com/2017/04/13/google-hire-is-a-job-site-that-diane-greenes-bebop-has-been-quietly-working-on/" rel="noopener noreferrer"&gt;Hire came from the Bebop acquisition that brought Diane Greene into Google&lt;/a&gt;. I suspect acquiring an amazing leader at the head of GCP may have been the primary goal.&lt;br&gt;&lt;br&gt;
[2] You need to &lt;a href="https://developers.google.com/hire/tenants/guides/getting-started" rel="noopener noreferrer"&gt;sign up and get approved for the Google Hire API&lt;/a&gt;. I wrote a pleading, but firm mail to our sales rep to nudge things along.&lt;/p&gt;




</description>
      <category>slack</category>
      <category>api</category>
      <category>integration</category>
    </item>
    <item>
      <title>Hypebot is the hype man who never lets me down</title>
      <dc:creator>Transposit</dc:creator>
      <pubDate>Tue, 19 Mar 2019 15:36:00 +0000</pubDate>
      <link>https://dev.to/transposit/hypebot-is-the-hype-man-who-never-lets-me-down-5bfm</link>
      <guid>https://dev.to/transposit/hypebot-is-the-hype-man-who-never-lets-me-down-5bfm</guid>
      <description>&lt;p&gt;Written by Sarah Brown&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F479%2F0%2AqtlNrmUh3TaXnaiH" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F479%2F0%2AqtlNrmUh3TaXnaiH"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The birth of hype
&lt;/h3&gt;

&lt;p&gt;It’s the middle of our company hackweek, and my hackweek project is not working. I’m trying to convert &lt;a href="http://www.bay12games.com/dwarves/" rel="noopener noreferrer"&gt;dwarf fortress release notes&lt;/a&gt; into emoji, but I keep hitting rate limits and — what’s maybe more detrimental — there is no emoji symbol for dwarf 🤷. I’m also vastly outnumbered in a Slack poll for what flavored waffles we’re buying for the office.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F623%2F0%2A2UDoLroq0OWeuhvf" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F623%2F0%2A2UDoLroq0OWeuhvf"&gt;&lt;/a&gt;Salted Caramel Conspiracy&lt;/p&gt;

&lt;p&gt;I know what I must do: abandon my hackweek project and write a slackbot that votes Apple Cinnamon. Unfortunately, the Slack API does not allow bots to click buttons 😒. I change tack and instead create &lt;strong&gt;hypebot&lt;/strong&gt; , a bot who reacts emphatically to everything I say in slack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AWqXjF0JYTNQQtNSu_iZrhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AWqXjF0JYTNQQtNSu_iZrhg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And Tuan too because he’s starved for hype.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AqsL9A6GWv93Hhyd2nLP2tw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AqsL9A6GWv93Hhyd2nLP2tw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The hype-cycle
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F722%2F0%2ADXaA3Nqd3t2rDkWf" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F722%2F0%2ADXaA3Nqd3t2rDkWf"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hypebot is built using Slack’s &lt;a href="https://api.slack.com/events-api" rel="noopener noreferrer"&gt;event subscription api&lt;/a&gt;, with the backend running on &lt;a href="https://www.transposit.com/" rel="noopener noreferrer"&gt;Transposit&lt;/a&gt;. You can check out all of hypebot’s code here: &lt;a href="https://console.transposit.com/t/transposit-sample/hypebot/code/op/webhook" rel="noopener noreferrer"&gt;https://console.transposit.com/t/transposit-sample/hypebot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2A3Y-xtwikGP0163Qy" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2A3Y-xtwikGP0163Qy"&gt;&lt;/a&gt;The Transposit Console&lt;/p&gt;

&lt;p&gt;When hypebot receives a message event from Slack, it splits the string into discrete words and looks each word up in the thesaurus. Then, armed with hundreds of synonyms, it compares each word to all potential Slack emojis. When it finds a match, it reacts. Thus the hype-cycle is complete.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F774%2F0%2AoO1UdIAatWfbO-N9" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F774%2F0%2AoO1UdIAatWfbO-N9"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Implementing this in Transposit meant I didn’t need to deploy my own server, and Transposit made it easy to keep track of bot OAuth scopes when making API calls. No infra; no auth; pure hype.&lt;/p&gt;

&lt;h3&gt;
  
  
  Taking it to the next level
&lt;/h3&gt;

&lt;p&gt;The hype train doesn’t end here. I’ve got upcoming hypebot posts about how we addressed performance problems when things were overhype, and how we can modify hypebot for his eventual debut on the Slack app directory. Of course if you’re too hype to wait, go ahead and &lt;a href="https://console.transposit.com/t/transposit-sample/hypebot?readme=true" rel="noopener noreferrer"&gt;fork hypebot on Transposit&lt;/a&gt; to build your own slackbot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AlEnHnzacA4aRbi_s" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AlEnHnzacA4aRbi_s"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sadly hypebot can’t add claps to a medium post via the api (believe me, I checked), so you’ll just have to do this the old fashioned way: 🙏👏&lt;/p&gt;




</description>
      <category>slackbot</category>
      <category>slack</category>
      <category>emoji</category>
      <category>api</category>
    </item>
    <item>
      <title>The Life Changing Magic of Migrating Github repositories with Transposit</title>
      <dc:creator>Transposit</dc:creator>
      <pubDate>Fri, 15 Mar 2019 15:31:00 +0000</pubDate>
      <link>https://dev.to/transposit/the-life-changing-magic-of-migrating-github-repositories-with-transposit-169g</link>
      <guid>https://dev.to/transposit/the-life-changing-magic-of-migrating-github-repositories-with-transposit-169g</guid>
      <description>&lt;p&gt;Written by Nina Yang&lt;/p&gt;

&lt;p&gt;I’m not a hoarder. I just &lt;em&gt;happen&lt;/em&gt; to manage a ton of GitHub repositories all shoved into one organization. But we need all of these repositories, I swear!&lt;/p&gt;

&lt;p&gt;To help developers easily interact with APIs, Transposit has built an assortment of connectors. Each connector lived in its own repository within a single GitHub org. But as our library of connectors grew, our org became more and more cluttered. It was time to &lt;a href="https://konmari.com/" rel="noopener noreferrer"&gt;KonMari&lt;/a&gt; them and tidy up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1000%2F0%2A_YeVcr2A2i1ZzK2G.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1000%2F0%2A_YeVcr2A2i1ZzK2G.png"&gt;&lt;/a&gt;Photo credit: &lt;a href="https://www.twotwentyone.net/nursery-dresser-organization/" rel="noopener noreferrer"&gt;twotwentyone.net&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The goal&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Create a new GitHub org and migrate our ~100 connector repositories over to it. Do this quickly and comprehensively to minimize disruption to developers interacting with these connectors.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The implementation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Of course I wanted to automate this — making processes like these straightforward was &lt;a href="https://dev.to/ellieseoejung/automation-through-the-eyes-of-an-engineer-2560-temp-slug-7154227"&gt;one of the reasons we built Transposit&lt;/a&gt;! But I was still surprised by how simple it was to translate the task into code.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 0: Create a new GitHub org
&lt;/h4&gt;

&lt;p&gt;I did this manually.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Fetch the repository names from the existing org
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AbRpGPK4WKGlLR__Fedk6jQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AbRpGPK4WKGlLR__Fedk6jQ.png"&gt;&lt;/a&gt;In Transposit, it’s one line of JavaScript&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Aq88dG-BzL0DLsonCQGQj9Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Aq88dG-BzL0DLsonCQGQj9Q.png"&gt;&lt;/a&gt;… or one line of SQL&lt;/p&gt;

&lt;p&gt;One of the great features of Transposit is that it takes care of the OAuth dance and credential storage for the developer. After storing a client ID and secret it was just a few clicks to allow Transposit access to my GitHub account.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: For each connector repository, create its namesake in the new org
&lt;/h4&gt;

&lt;p&gt;When we were crowding all our repos into one GitHub org, we used the prefix “app_” to distinguish our connector repositories from other code (our main codebase and supporting projects). Thus, I could use this prefix to identify the correct repositories to migrate and then drop it because it was no longer needed.&lt;/p&gt;

&lt;p&gt;I made an operation that created the new repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AofAINd4aFhPelj7WKJ_4lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AofAINd4aFhPelj7WKJ_4lg.png"&gt;&lt;/a&gt;This operation can be invoked as “this.create_repo_in_org”&lt;/p&gt;

&lt;p&gt;My main operation applies it to all repos with the “app_” prefix:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AVGF1YanI94vBqVZixhQkvg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AVGF1YanI94vBqVZixhQkvg.png"&gt;&lt;/a&gt;Not bad for &amp;lt;20 lines of code.&lt;/p&gt;

&lt;p&gt;I hit the “Run” button, and off it went.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Realize that I’ve accidentally created all the new repositories as public and run a fix
&lt;/h4&gt;

&lt;p&gt;Some of our connectors are open source, and some are still a work-in-progress and not &lt;em&gt;quite&lt;/em&gt; ready to be public. Whoops. Fortunately, with Transposit it was simple to change them back to private.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AYYysFV0v6PVHBCY6UG8Blw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AYYysFV0v6PVHBCY6UG8Blw.png"&gt;&lt;/a&gt;Whew!&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Step 4: Migrate repository contents&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;I used a python script to copy the repository contents into their new homes. &lt;strong&gt;However&lt;/strong&gt; , while writing this blog post I discovered that GitHub provides an actual &lt;a href="https://developer.github.com/changes/2017-11-09-repository-transfer-api-preview/" rel="noopener noreferrer"&gt;repository transfer API&lt;/a&gt; I could’ve used which would have taken care of this step, and combining it with Transposit would’ve made the process even easier. Welp… good information for next time.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Step 5: Notify my team to update their local repository remotes to point to the new org&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;I wrote another script to do this. Again, it would’ve been better to use the repository transfer API, which will warn you about the updated remote &lt;em&gt;and&lt;/em&gt; still push to the new repository.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 6: Delete the old repositories
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ALyunFasxPvCv-obM1simxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ALyunFasxPvCv-obM1simxw.png"&gt;&lt;/a&gt;Look familiar?&lt;/p&gt;

&lt;h3&gt;
  
  
  The end
&lt;/h3&gt;

&lt;p&gt;There are other ways this migration could’ve been done. I could’ve manually transferred ownership of all the repos via the GitHub UI, but that would’ve taken forever. I could’ve done the migration using raw requests to the GitHub APIs, but that would’ve required poring over API and authentication documentation, and would’ve created more opportunities for error. There are also GitHub-specific CLIs that would have achieved the same outcome, but necessitated learning syntax that I was not likely to use again.&lt;/p&gt;

&lt;p&gt;With Transposit, I used JavaScript and SQL to complete the migration in a few hours. The details of my API calls were abstracted away and I got to focus on the logic of my implementation rather than the minutiae of the setup steps. The process was quick and efficient and now all of our repositories are in their proper place.&lt;/p&gt;

&lt;p&gt;Your use case might be different, but your sentiment of wanting to build without getting sidetracked in tedium could be the same. Maybe &lt;a href="https://www.transposit.com/" rel="noopener noreferrer"&gt;Transposit&lt;/a&gt; can spark joy for you too.&lt;/p&gt;




</description>
      <category>softwaredevelopment</category>
      <category>github</category>
      <category>sql</category>
      <category>api</category>
    </item>
    <item>
      <title>SQL order from API chaos</title>
      <dc:creator>Transposit</dc:creator>
      <pubDate>Thu, 07 Mar 2019 20:44:27 +0000</pubDate>
      <link>https://dev.to/transposit/sql-order-from-api-chaos-3eik</link>
      <guid>https://dev.to/transposit/sql-order-from-api-chaos-3eik</guid>
      <description>&lt;p&gt;Written by Tina Huang @kmonkeyjam&lt;/p&gt;

&lt;p&gt;Developing any application in a world powered by SaaS requires you to work with and cater to numerous APIs. That wasn’t always the case.&lt;/p&gt;

&lt;p&gt;When I first started out at Apple as an application frameworks engineer, components that people built would render from a single data source, almost always a local database. But by the time I joined the engineering team at Twitter in 2009, the world had moved to an API-driven ecosystem. At Twitter, we used APIs for internal microservice communication as well as to publicize data to external developers. Having to glue together all these APIs, both internal and external, was pure drudgery that resulted in a lot of spaghetti code. Composing APIs for developers who haven’t been working with them for the past decade can be mind-bogglingly complex.&lt;/p&gt;

&lt;p&gt;It’s hard to believe there’s not a good solution to the problem of API composition. There are so many platforms to help you find APIs, make that initial connection, and even call a single API. But there is no dedicated platform that helps weave data from APIs together in a streamlined way — while also handling the numerous operational chores required from modern APIs, like authentication, pagination, retries, and so much more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing Transposit
&lt;/h3&gt;

&lt;p&gt;This is a layer that needs to exist, and for the past two years, &lt;a href="https://www.transposit.com/" rel="noopener noreferrer"&gt;we’ve been building Transposit as the solution to this problem&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Transposit is a zero-ops platform that brings the power of a relational database to the API ecosystem. Our relational engine provides the ability to write SQL and JavaScript to query and transform your data as though each data connection were a virtual table in a single relational database.&lt;/p&gt;

&lt;p&gt;While a database has unfettered access to its raw data on disk, APIs protect your data with authentication. To make a relational engine work in this new data landscape, we’ve built in authentication management not only for you as a developer accessing your own data, but also for all your application’s users and their data sources. The result is a seamless way to query data regardless of where it lives.&lt;/p&gt;

&lt;p&gt;Transposit abstracts away the details of specific API mechanics and lets you focus on the code that makes your application unique. It does this by allowing you to easily express your intent in a higher-level language of joins and filters, then translating that intent into a number of optimized API calls. It deals with all aspects of communicating with modern APIs such as retries, re-auth, and pagination. It implements security best practices so that you don’t have to. The UI provides an interactive and playful way for you to explore your data as you build your application. For example, teams often use Slack to communicate and triage issues that happen during production incidents. So let’s say you want to make it easy to file a bug in Jira and attach some production logs stored in AWS Cloudwatch, all from within your Slack triage channel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AdTxivWymZK8dQTd_UXD5Og.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AdTxivWymZK8dQTd_UXD5Og.png"&gt;&lt;/a&gt;A Transposit webhook operation that files an issue in Jira with Cloudwatch logs&lt;/p&gt;

&lt;p&gt;To do this without Transposit, you would need to learn the intricacies of the Jira, AWS, and Slack APIs. You’d also need to host a server to receive the Slack webhook, securely store credentials, and implement a bunch of tedious logic. All this work makes it too daunting and too frustrating to build — even though this would be an amazing time saver during an actual incident.&lt;/p&gt;

&lt;p&gt;Enter Transposit: now you have the ability to rapidly compose logic across multiple APIs without having to handle any of the API complexities. You can quickly build an application and have Transposit manage all of the deployment details. The joy of Transposit is that it’s fast and fun to turn your idea into an application, and it’s also easy to debug, improve, and share it with others.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AL54zY16km8p-6usKZn8TfA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AL54zY16km8p-6usKZn8TfA.png"&gt;&lt;/a&gt;The Transposit UI in action&lt;/p&gt;

&lt;p&gt;Today, we’ve opened a public Beta for Transposit. &lt;a href="http://www.prweb.com/releases/transposit_raises_12_2m_from_sutter_hill_ventures_and_signalfire_for_the_industrys_first_api_composition_platform_for_developers/prweb16149393.htm" rel="noopener noreferrer"&gt;We’ve also raised $12.2M in Series A funding&lt;/a&gt;, which gives us the resources we need to grow and engage with the community.&lt;/p&gt;

&lt;p&gt;Tell us what you wish you could build with APIs, and what’s holding you back. What is the most annoying challenge you have to deal with? How is your creativity being hampered by API drudgery? We hope you’ll sign up for our Beta, tinker around, and let us know what you think — and what you build!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.transposit.com" rel="noopener noreferrer"&gt;Sign up&lt;/a&gt;&lt;/p&gt;




</description>
      <category>serverless</category>
      <category>javascript</category>
      <category>api</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
