{"id":11304,"date":"2017-08-23T04:56:42","date_gmt":"2017-08-23T04:56:42","guid":{"rendered":"https:\/\/passkit.com\/blog\/?p=11304"},"modified":"2017-08-23T04:56:42","modified_gmt":"2017-08-23T04:56:42","slug":"how-to-use-golang-aws-lambda-to-build-a-scalable-barcode-generator-part-2","status":"publish","type":"post","link":"https:\/\/passkit.com\/blog\/how-to-use-golang-aws-lambda-to-build-a-scalable-barcode-generator-part-2\/","title":{"rendered":"How to use Golang &amp; AWS Lambda to build a scalable Barcode Generator (Part 2)"},"content":{"rendered":"<p><em>Note: this is part 2 in a 2 part series. Please click <a href=\"https:\/\/passkit.com\/blog\/how-to-use-golang-aws-lambda-to-build-a-scalable-barcode-generator-part-1\/\">here<\/a> for part 1 (running Go in an AWS Lambda).<\/em><\/p>\n<h3>5. Setup API Gateway<\/h3>\n<p>Login to your AWS account, and navigate to API Gateway.<br \/>\n<em>1. Create a new API:<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101050\/api-gateway-flow.001.jpeg\" target=\"_blank\" rel=\"noopener\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101050\/api-gateway-flow.001.jpeg\" alt=\"api-gateway-flow.001\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11331\" title=\"\"><\/a><br \/>\n<em>2. Name the API:<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101058\/api-gateway-flow.002.jpeg\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101058\/api-gateway-flow.002.jpeg\" alt=\"api-gateway-flow.002\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11332\" title=\"\"><\/a><br \/>\n<em>3. Add &#038; configure the resource:<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101106\/api-gateway-flow.003.jpeg\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101106\/api-gateway-flow.003.jpeg\" alt=\"api-gateway-flow.003\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11333\" title=\"\"><\/a><br \/>\n<em>Make sure to check &#8216;Enable API Gateway CORS&#8217;. This will result in API Gateway automatically setting up an OPTIONS method with basic CORS configuration allowing all origins, all methods, and several common headers. You can manually add more strict rules to this at a later stage.<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101114\/api-gateway-flow.004.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101114\/api-gateway-flow.004.jpeg\" alt=\"api-gateway-flow.004\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11334\" title=\"\"><\/a><br \/>\n<em>4. Create &#038; configure the HTTP GET method for the resource:<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100946\/api-gateway-flow.005.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100946\/api-gateway-flow.005.jpeg\" alt=\"api-gateway-flow.005\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11323\" title=\"\"><\/a><br \/>\n<em>Point the method to the Lambda function created in <a href=\"https:\/\/passkit.com\/blog\/how-to-use-golang-aws-lambda-to-build-a-scalable-barcode-generator-part-1\/\">Part 1<\/a>.<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100954\/api-gateway-flow.006.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100954\/api-gateway-flow.006.jpeg\" alt=\"api-gateway-flow.006\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11324\" title=\"\"><\/a><br \/>\n<em>Grant the method permissions to access your lambda.<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101002\/api-gateway-flow.007.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101002\/api-gateway-flow.007.jpeg\" alt=\"api-gateway-flow.007\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11325\" title=\"\"><\/a><br \/>\n<em>5. Setup the GET Parameters in the Method Request:<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101010\/api-gateway-flow.008.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101010\/api-gateway-flow.008.jpeg\" alt=\"api-gateway-flow.008\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11326\" title=\"\"><\/a><br \/>\n<em>All of the parameters that are setup here can be passed into the final URL of the endpoint. In the next steps these will be mapped to the Lambda.<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101018\/api-gateway-flow.009.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101018\/api-gateway-flow.009.jpeg\" alt=\"api-gateway-flow.009\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11327\" title=\"\"><\/a><br \/>\n<em>6. Setup the Integration Request &#038; Template Mapping:<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101034\/api-gateway-flow.011.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101034\/api-gateway-flow.011.jpeg\" alt=\"api-gateway-flow.011\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11329\" title=\"\"><\/a><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101042\/api-gateway-flow.012.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17101042\/api-gateway-flow.012.jpeg\" alt=\"api-gateway-flow.012\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11330\" title=\"\"><\/a><br \/>\n<em>Next is where the JSON object is specified that is passed into the Lambda function as the eventJSON. In the integration template the request parameters can be accessed by using <strong>$json.params(&#8216;paramName&#8217;)<\/strong>.<\/em><br \/>\n<em>In our case, the first two parameters width &#038; height are mapped as integers, and the second 2 parameters are mapped as string.<\/em><br \/>\n<em>For more details on API Gateway mapping templates, have a look <a href=\"http:\/\/docs.aws.amazon.com\/apigateway\/latest\/developerguide\/api-gateway-mapping-template-reference.html\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100834\/api-gateway-flow.013.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100834\/api-gateway-flow.013.jpeg\" alt=\"api-gateway-flow.013\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11314\" title=\"\"><\/a><br \/>\n<em>7. Setup the Method Response:<\/em><br \/>\n<em>This is where all the possible HTTP response codes are defined. In case of our barcode generator endpoint, we only return 200, 400 &#038; 500.<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100850\/api-gateway-flow.015.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100850\/api-gateway-flow.015.jpeg\" alt=\"api-gateway-flow.015\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11316\" title=\"\"><\/a><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100858\/api-gateway-flow.016.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100858\/api-gateway-flow.016.jpeg\" alt=\"api-gateway-flow.016\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11317\" title=\"\"><\/a><br \/>\n<em>For the 200 status we need to define 2 response headers: Allow-Access-Control-Origin &#038; Content-Type. Content-Type is required so that the API Gateway method integration can map the Lambda base64 encoded image response to the correct image Content-Type: image\/png.<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100906\/api-gateway-flow.017.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100906\/api-gateway-flow.017.jpeg\" alt=\"api-gateway-flow.017\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11318\" title=\"\"><\/a><br \/>\n<em>8. Setup the Integration Response and Binary Conversion:<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100922\/api-gateway-flow.019.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100922\/api-gateway-flow.019.jpeg\" alt=\"api-gateway-flow.019\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11320\" title=\"\"><\/a><br \/>\n<em>It is important to set &#8216;<strong>Content Handling<\/strong>&#8216; to &#8216;<strong> CONVERT_TO_BINARY <\/strong>&#8216;.<\/em><br \/>\n<em>Do not define a mapping template. When you do not define a mapping template, API Gateway invokes the passthrough template to return the Base64-decoded binary blob as the image file to the client.<\/em><br \/>\n<em>API Gateway converts results into binary content if:<\/p>\n<ul>\n<li>The result content type matches one of the pre-configured binary content types, and<\/li>\n<li>The response content handling is set to &#8216;CONVERT_TO_BINARY&#8217;.<\/li>\n<\/ul>\n<p><a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100930\/api-gateway-flow.020.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100930\/api-gateway-flow.020.jpeg\" alt=\"api-gateway-flow.020\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11321\" title=\"\"><\/a><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100938\/api-gateway-flow.021.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100938\/api-gateway-flow.021.jpeg\" alt=\"api-gateway-flow.021\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11322\" title=\"\"><\/a><br \/>\n<em>To add binary support for the content type, you need to add the content-type in the &#8216;<strong>Binary Support<\/strong>&#8216; section:<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100744\/api-gateway-flow.024.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100744\/api-gateway-flow.024.jpeg\" alt=\"api-gateway-flow.024\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11308\" title=\"\"><\/a><br \/>\n<em>9. Add integration responses for the 400 &#038; 500 error codes:<\/em><br \/>\n<em>When provided with an error regex, API Gateway will map the Lambda error responses to the correct HTTP method response statuses.<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100737\/api-gateway-flow.023.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100737\/api-gateway-flow.023.jpeg\" alt=\"api-gateway-flow.023\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11307\" title=\"\"><\/a><br \/>\n<em>10. Testing with a correct \/ incorrect payload:<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100752\/api-gateway-flow.025.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100752\/api-gateway-flow.025.jpeg\" alt=\"api-gateway-flow.025\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11309\" title=\"\"><\/a><br \/>\n<em>That looks good &#8211; the endpoint is returning the correct status code, content-type and binary data:<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100801\/api-gateway-flow.026.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100801\/api-gateway-flow.026.jpeg\" alt=\"api-gateway-flow.026\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11310\" title=\"\"><\/a><br \/>\n<em>When using a bad request payload, we get a 400 status code, with a JSON error response.<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100809\/api-gateway-flow.027.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100809\/api-gateway-flow.027.jpeg\" alt=\"api-gateway-flow.027\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11311\" title=\"\"><\/a><br \/>\n<em>11. Deploy the API and get the URL to invoke your endpoint:<\/em><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100818\/api-gateway-flow.028.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100818\/api-gateway-flow.028.jpeg\" alt=\"api-gateway-flow.028\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11312\" title=\"\"><\/a><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100721\/api-gateway-flow.030.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100721\/api-gateway-flow.030.jpeg\" alt=\"api-gateway-flow.030\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11305\" title=\"\"><\/a><br \/>\n<a href=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100826\/api-gateway-flow.029.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dxjl3qy52c1o9.cloudfront.net\/wp-content\/uploads\/2017\/08\/17100826\/api-gateway-flow.029.jpeg\" alt=\"api-gateway-flow.029\" width=\"1024\" height=\"640\" class=\"alignnone size-full wp-image-11313\" title=\"\"><\/a><br \/>\nWe now have our Invoke URL, and can append this with &#8216;<strong>\/barcode<\/strong>&#8216; plus our request parameters. This URL can be used as the source of an image:<br \/>\n<strong>https:\/\/41xevk8avc.execute-api.us-east-1.amazonaws.com\/Production\/barcode?message=testing&#038;width=200&#038;height=200&#038;type=qr<\/strong><br \/>\n&#8211; OR &#8211;<br \/>\n[html]<br \/>\n&lt;img src=&quot;https:\/\/41xevk8avc.execute-api.us-east-1.amazonaws.com\/Production\/barcode?message=testing&amp;width=200&amp;height=200&amp;type=qr&quot; alt=&quot;QR Code&quot;\/&gt;<br \/>\n[\/html]<br \/>\nAnd we are done! To summarise, you now have an understanding on how to:<\/p>\n<ul>\n<li>Write golang functions for AWS Lambda.\n<li>Use AWS API Gateway to return binary content.\n<li>Link together AWS Lambda &#038; API Gateway to create a scalable HTTPS service for barcode generation.\n<\/ul>\n<p>If you would like to setup a custom domain name for the URL of the endpoint &#8211; for example have something like:<br \/>\nhttps:\/\/api.myprettyurl.com\/barcode<br \/>\nYou can do so by following the steps in <a href=\"http:\/\/docs.aws.amazon.com\/apigateway\/latest\/developerguide\/how-to-custom-domains.html\" target=\"_blank\" rel=\"noopener\">this<\/a> article.<br \/>\nPlease leave your comments. I would love to hear if any of you were able to create some other cool web-services using the techniques explained in this article. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Note: this is part 2 in a 2 part series. Please click here for part 1 (running Go in an AWS Lambda). 5. Setup API Gateway Login to your AWS account, and navigate to API Gateway. 1. Create a new API: 2. Name the API: 3. Add &#038; configure the resource: Make sure to check [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":13751,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[37],"tags":[],"class_list":["post-11304","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech"],"_links":{"self":[{"href":"https:\/\/passkit.com\/blog\/wp-json\/wp\/v2\/posts\/11304","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/passkit.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/passkit.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/passkit.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/passkit.com\/blog\/wp-json\/wp\/v2\/comments?post=11304"}],"version-history":[{"count":0,"href":"https:\/\/passkit.com\/blog\/wp-json\/wp\/v2\/posts\/11304\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/passkit.com\/blog\/wp-json\/wp\/v2\/media\/13751"}],"wp:attachment":[{"href":"https:\/\/passkit.com\/blog\/wp-json\/wp\/v2\/media?parent=11304"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/passkit.com\/blog\/wp-json\/wp\/v2\/categories?post=11304"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/passkit.com\/blog\/wp-json\/wp\/v2\/tags?post=11304"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}