[{"data":1,"prerenderedAt":1086},["ShallowReactive",2],{"post-cloud-functions-serverless-app":3},{"id":4,"title":5,"body":6,"date":1074,"description":1075,"extension":1076,"meta":1077,"navigation":233,"path":1082,"seo":1083,"stem":1084,"__hash__":1085},"blog\u002Fblog\u002Fcloud-functions-serverless-app.md","Google Cloud FunctionsとCloud SQLの連携",{"type":7,"value":8,"toc":1058},"minimark",[9,14,18,24,52,56,59,171,174,189,193,196,200,203,317,320,552,555,858,861,864,938,941,945,948,1002,1006,1009,1013,1016,1019,1022,1027,1038,1043,1054],[10,11,13],"h2",{"id":12},"cloud-functionsとは","Cloud Functionsとは",[15,16,17],"p",{},"Google Cloud FunctionsはGCPが提供するサーバーレス実行環境です。",[15,19,20],{},[21,22,23],"strong",{},"主な特徴",[25,26,27,34,40,46],"ul",{},[28,29,30,33],"li",{},[21,31,32],{},"サーバー管理不要"," インフラの管理や運用が不要",[28,35,36,39],{},[21,37,38],{},"自動スケーリング"," 負荷に応じて自動的にスケール",[28,41,42,45],{},[21,43,44],{},"従量課金"," 実行時間に応じた課金モデル",[28,47,48,51],{},[21,49,50],{},"イベント駆動"," HTTPリクエストやCloud Storageの変更などをトリガーに実行",[10,53,55],{"id":54},"基本的なhttp関数","基本的なHTTP関数",[15,57,58],{},"最もシンプルなHTTPトリガーの例です。",[60,61,66],"pre",{"className":62,"code":63,"language":64,"meta":65,"style":65},"language-js shiki shiki-themes github-light github-dark","exports.helloWorld = (req, res) => {\n  const message = req.query.message || req.body.message || 'Hello GCP!';\n  res.status(200).send(message);\n};\n","js","",[67,68,69,112,141,165],"code",{"__ignoreMap":65},[70,71,74,78,82,86,90,93,97,100,103,106,109],"span",{"class":72,"line":73},"line",1,[70,75,77],{"class":76},"sj4cs","exports",[70,79,81],{"class":80},"sVt8B",".",[70,83,85],{"class":84},"sScJk","helloWorld",[70,87,89],{"class":88},"szBVR"," =",[70,91,92],{"class":80}," (",[70,94,96],{"class":95},"s4XuR","req",[70,98,99],{"class":80},", ",[70,101,102],{"class":95},"res",[70,104,105],{"class":80},") ",[70,107,108],{"class":88},"=>",[70,110,111],{"class":80}," {\n",[70,113,115,118,121,123,126,129,132,134,138],{"class":72,"line":114},2,[70,116,117],{"class":88},"  const",[70,119,120],{"class":76}," message",[70,122,89],{"class":88},[70,124,125],{"class":80}," req.query.message ",[70,127,128],{"class":88},"||",[70,130,131],{"class":80}," req.body.message ",[70,133,128],{"class":88},[70,135,137],{"class":136},"sZZnC"," 'Hello GCP!'",[70,139,140],{"class":80},";\n",[70,142,144,147,150,153,156,159,162],{"class":72,"line":143},3,[70,145,146],{"class":80},"  res.",[70,148,149],{"class":84},"status",[70,151,152],{"class":80},"(",[70,154,155],{"class":76},"200",[70,157,158],{"class":80},").",[70,160,161],{"class":84},"send",[70,163,164],{"class":80},"(message);\n",[70,166,168],{"class":72,"line":167},4,[70,169,170],{"class":80},"};\n",[15,172,173],{},"デプロイ後、トリガーURLにアクセスすることで関数が実行されます。",[60,175,179],{"className":176,"code":177,"language":178,"meta":65,"style":65},"language-bash shiki shiki-themes github-light github-dark","curl https:\u002F\u002FREGION-PROJECT_ID.cloudfunctions.net\u002FhelloWorld?message=こんにちは\n","bash",[67,180,181],{"__ignoreMap":65},[70,182,183,186],{"class":72,"line":73},[70,184,185],{"class":84},"curl",[70,187,188],{"class":136}," https:\u002F\u002FREGION-PROJECT_ID.cloudfunctions.net\u002FhelloWorld?message=こんにちは\n",[10,190,192],{"id":191},"cloud-sqlとの連携","Cloud SQLとの連携",[15,194,195],{},"Cloud FunctionsからCloud SQLに接続する方法を紹介します。",[197,198,199],"h3",{"id":199},"接続設定",[15,201,202],{},"Cloud SQLへの接続には、Unix Domainソケットを使用します。",[60,204,206],{"className":62,"code":205,"language":64,"meta":65,"style":65},"const mysql = require('mysql');\n\nconst connection = mysql.createConnection({\n  socketPath: `\u002Fcloudsql\u002F${process.env.CLOUD_SQL_CONNECTION_NAME}`,\n  user: process.env.DB_USER,\n  password: process.env.DB_PASSWORD,\n  database: process.env.DB_NAME\n});\n",[67,207,208,229,235,253,280,291,302,311],{"__ignoreMap":65},[70,209,210,213,216,218,221,223,226],{"class":72,"line":73},[70,211,212],{"class":88},"const",[70,214,215],{"class":76}," mysql",[70,217,89],{"class":88},[70,219,220],{"class":84}," require",[70,222,152],{"class":80},[70,224,225],{"class":136},"'mysql'",[70,227,228],{"class":80},");\n",[70,230,231],{"class":72,"line":114},[70,232,234],{"emptyLinePlaceholder":233},true,"\n",[70,236,237,239,242,244,247,250],{"class":72,"line":143},[70,238,212],{"class":88},[70,240,241],{"class":76}," connection",[70,243,89],{"class":88},[70,245,246],{"class":80}," mysql.",[70,248,249],{"class":84},"createConnection",[70,251,252],{"class":80},"({\n",[70,254,255,258,261,264,266,269,271,274,277],{"class":72,"line":167},[70,256,257],{"class":80},"  socketPath: ",[70,259,260],{"class":136},"`\u002Fcloudsql\u002F${",[70,262,263],{"class":80},"process",[70,265,81],{"class":136},[70,267,268],{"class":80},"env",[70,270,81],{"class":136},[70,272,273],{"class":76},"CLOUD_SQL_CONNECTION_NAME",[70,275,276],{"class":136},"}`",[70,278,279],{"class":80},",\n",[70,281,283,286,289],{"class":72,"line":282},5,[70,284,285],{"class":80},"  user: process.env.",[70,287,288],{"class":76},"DB_USER",[70,290,279],{"class":80},[70,292,294,297,300],{"class":72,"line":293},6,[70,295,296],{"class":80},"  password: process.env.",[70,298,299],{"class":76},"DB_PASSWORD",[70,301,279],{"class":80},[70,303,305,308],{"class":72,"line":304},7,[70,306,307],{"class":80},"  database: process.env.",[70,309,310],{"class":76},"DB_NAME\n",[70,312,314],{"class":72,"line":313},8,[70,315,316],{"class":80},"});\n",[197,318,319],{"id":319},"データ取得の実装例",[60,321,323],{"className":62,"code":322,"language":64,"meta":65,"style":65},"exports.getUsers = async (req, res) => {\n  const connection = mysql.createConnection({\n    socketPath: `\u002Fcloudsql\u002F${process.env.CLOUD_SQL_CONNECTION_NAME}`,\n    user: process.env.DB_USER,\n    password: process.env.DB_PASSWORD,\n    database: process.env.DB_NAME\n  });\n\n  connection.query('SELECT * FROM users', (err, results) => {\n    if (err) {\n      console.error(err);\n      res.status(500).json({ error: 'Database error' });\n      return;\n    }\n    res.json(results);\n  });\n\n  connection.end();\n};\n",[67,324,325,353,367,388,397,406,413,418,422,453,462,474,501,509,515,526,531,536,547],{"__ignoreMap":65},[70,326,327,329,331,334,336,339,341,343,345,347,349,351],{"class":72,"line":73},[70,328,77],{"class":76},[70,330,81],{"class":80},[70,332,333],{"class":84},"getUsers",[70,335,89],{"class":88},[70,337,338],{"class":88}," async",[70,340,92],{"class":80},[70,342,96],{"class":95},[70,344,99],{"class":80},[70,346,102],{"class":95},[70,348,105],{"class":80},[70,350,108],{"class":88},[70,352,111],{"class":80},[70,354,355,357,359,361,363,365],{"class":72,"line":114},[70,356,117],{"class":88},[70,358,241],{"class":76},[70,360,89],{"class":88},[70,362,246],{"class":80},[70,364,249],{"class":84},[70,366,252],{"class":80},[70,368,369,372,374,376,378,380,382,384,386],{"class":72,"line":143},[70,370,371],{"class":80},"    socketPath: ",[70,373,260],{"class":136},[70,375,263],{"class":80},[70,377,81],{"class":136},[70,379,268],{"class":80},[70,381,81],{"class":136},[70,383,273],{"class":76},[70,385,276],{"class":136},[70,387,279],{"class":80},[70,389,390,393,395],{"class":72,"line":167},[70,391,392],{"class":80},"    user: process.env.",[70,394,288],{"class":76},[70,396,279],{"class":80},[70,398,399,402,404],{"class":72,"line":282},[70,400,401],{"class":80},"    password: process.env.",[70,403,299],{"class":76},[70,405,279],{"class":80},[70,407,408,411],{"class":72,"line":293},[70,409,410],{"class":80},"    database: process.env.",[70,412,310],{"class":76},[70,414,415],{"class":72,"line":304},[70,416,417],{"class":80},"  });\n",[70,419,420],{"class":72,"line":313},[70,421,234],{"emptyLinePlaceholder":233},[70,423,425,428,431,433,436,439,442,444,447,449,451],{"class":72,"line":424},9,[70,426,427],{"class":80},"  connection.",[70,429,430],{"class":84},"query",[70,432,152],{"class":80},[70,434,435],{"class":136},"'SELECT * FROM users'",[70,437,438],{"class":80},", (",[70,440,441],{"class":95},"err",[70,443,99],{"class":80},[70,445,446],{"class":95},"results",[70,448,105],{"class":80},[70,450,108],{"class":88},[70,452,111],{"class":80},[70,454,456,459],{"class":72,"line":455},10,[70,457,458],{"class":88},"    if",[70,460,461],{"class":80}," (err) {\n",[70,463,465,468,471],{"class":72,"line":464},11,[70,466,467],{"class":80},"      console.",[70,469,470],{"class":84},"error",[70,472,473],{"class":80},"(err);\n",[70,475,477,480,482,484,487,489,492,495,498],{"class":72,"line":476},12,[70,478,479],{"class":80},"      res.",[70,481,149],{"class":84},[70,483,152],{"class":80},[70,485,486],{"class":76},"500",[70,488,158],{"class":80},[70,490,491],{"class":84},"json",[70,493,494],{"class":80},"({ error: ",[70,496,497],{"class":136},"'Database error'",[70,499,500],{"class":80}," });\n",[70,502,504,507],{"class":72,"line":503},13,[70,505,506],{"class":88},"      return",[70,508,140],{"class":80},[70,510,512],{"class":72,"line":511},14,[70,513,514],{"class":80},"    }\n",[70,516,518,521,523],{"class":72,"line":517},15,[70,519,520],{"class":80},"    res.",[70,522,491],{"class":84},[70,524,525],{"class":80},"(results);\n",[70,527,529],{"class":72,"line":528},16,[70,530,417],{"class":80},[70,532,534],{"class":72,"line":533},17,[70,535,234],{"emptyLinePlaceholder":233},[70,537,539,541,544],{"class":72,"line":538},18,[70,540,427],{"class":80},[70,542,543],{"class":84},"end",[70,545,546],{"class":80},"();\n",[70,548,550],{"class":72,"line":549},19,[70,551,170],{"class":80},[197,553,554],{"id":554},"データ登録の実装例",[60,556,558],{"className":62,"code":557,"language":64,"meta":65,"style":65},"exports.createUser = async (req, res) => {\n  const { name } = req.body;\n\n  if (!name) {\n    res.status(400).json({ error: 'Name is required' });\n    return;\n  }\n\n  const connection = mysql.createConnection({\n    socketPath: `\u002Fcloudsql\u002F${process.env.CLOUD_SQL_CONNECTION_NAME}`,\n    user: process.env.DB_USER,\n    password: process.env.DB_PASSWORD,\n    database: process.env.DB_NAME\n  });\n\n  connection.query(\n    'INSERT INTO users (name) VALUES (?)',\n    [name],\n    (err, result) => {\n      if (err) {\n        console.error(err);\n        res.status(500).json({ error: 'Database error' });\n        return;\n      }\n      res.json({ id: result.insertId, name });\n    }\n  );\n\n  connection.end();\n};\n",[67,559,560,587,606,610,623,645,652,657,661,675,695,703,711,717,721,725,734,741,746,764,772,782,804,812,818,828,833,839,844,853],{"__ignoreMap":65},[70,561,562,564,566,569,571,573,575,577,579,581,583,585],{"class":72,"line":73},[70,563,77],{"class":76},[70,565,81],{"class":80},[70,567,568],{"class":84},"createUser",[70,570,89],{"class":88},[70,572,338],{"class":88},[70,574,92],{"class":80},[70,576,96],{"class":95},[70,578,99],{"class":80},[70,580,102],{"class":95},[70,582,105],{"class":80},[70,584,108],{"class":88},[70,586,111],{"class":80},[70,588,589,591,594,597,600,603],{"class":72,"line":114},[70,590,117],{"class":88},[70,592,593],{"class":80}," { ",[70,595,596],{"class":76},"name",[70,598,599],{"class":80}," } ",[70,601,602],{"class":88},"=",[70,604,605],{"class":80}," req.body;\n",[70,607,608],{"class":72,"line":143},[70,609,234],{"emptyLinePlaceholder":233},[70,611,612,615,617,620],{"class":72,"line":167},[70,613,614],{"class":88},"  if",[70,616,92],{"class":80},[70,618,619],{"class":88},"!",[70,621,622],{"class":80},"name) {\n",[70,624,625,627,629,631,634,636,638,640,643],{"class":72,"line":282},[70,626,520],{"class":80},[70,628,149],{"class":84},[70,630,152],{"class":80},[70,632,633],{"class":76},"400",[70,635,158],{"class":80},[70,637,491],{"class":84},[70,639,494],{"class":80},[70,641,642],{"class":136},"'Name is required'",[70,644,500],{"class":80},[70,646,647,650],{"class":72,"line":293},[70,648,649],{"class":88},"    return",[70,651,140],{"class":80},[70,653,654],{"class":72,"line":304},[70,655,656],{"class":80},"  }\n",[70,658,659],{"class":72,"line":313},[70,660,234],{"emptyLinePlaceholder":233},[70,662,663,665,667,669,671,673],{"class":72,"line":424},[70,664,117],{"class":88},[70,666,241],{"class":76},[70,668,89],{"class":88},[70,670,246],{"class":80},[70,672,249],{"class":84},[70,674,252],{"class":80},[70,676,677,679,681,683,685,687,689,691,693],{"class":72,"line":455},[70,678,371],{"class":80},[70,680,260],{"class":136},[70,682,263],{"class":80},[70,684,81],{"class":136},[70,686,268],{"class":80},[70,688,81],{"class":136},[70,690,273],{"class":76},[70,692,276],{"class":136},[70,694,279],{"class":80},[70,696,697,699,701],{"class":72,"line":464},[70,698,392],{"class":80},[70,700,288],{"class":76},[70,702,279],{"class":80},[70,704,705,707,709],{"class":72,"line":476},[70,706,401],{"class":80},[70,708,299],{"class":76},[70,710,279],{"class":80},[70,712,713,715],{"class":72,"line":503},[70,714,410],{"class":80},[70,716,310],{"class":76},[70,718,719],{"class":72,"line":511},[70,720,417],{"class":80},[70,722,723],{"class":72,"line":517},[70,724,234],{"emptyLinePlaceholder":233},[70,726,727,729,731],{"class":72,"line":528},[70,728,427],{"class":80},[70,730,430],{"class":84},[70,732,733],{"class":80},"(\n",[70,735,736,739],{"class":72,"line":533},[70,737,738],{"class":136},"    'INSERT INTO users (name) VALUES (?)'",[70,740,279],{"class":80},[70,742,743],{"class":72,"line":538},[70,744,745],{"class":80},"    [name],\n",[70,747,748,751,753,755,758,760,762],{"class":72,"line":549},[70,749,750],{"class":80},"    (",[70,752,441],{"class":95},[70,754,99],{"class":80},[70,756,757],{"class":95},"result",[70,759,105],{"class":80},[70,761,108],{"class":88},[70,763,111],{"class":80},[70,765,767,770],{"class":72,"line":766},20,[70,768,769],{"class":88},"      if",[70,771,461],{"class":80},[70,773,775,778,780],{"class":72,"line":774},21,[70,776,777],{"class":80},"        console.",[70,779,470],{"class":84},[70,781,473],{"class":80},[70,783,785,788,790,792,794,796,798,800,802],{"class":72,"line":784},22,[70,786,787],{"class":80},"        res.",[70,789,149],{"class":84},[70,791,152],{"class":80},[70,793,486],{"class":76},[70,795,158],{"class":80},[70,797,491],{"class":84},[70,799,494],{"class":80},[70,801,497],{"class":136},[70,803,500],{"class":80},[70,805,807,810],{"class":72,"line":806},23,[70,808,809],{"class":88},"        return",[70,811,140],{"class":80},[70,813,815],{"class":72,"line":814},24,[70,816,817],{"class":80},"      }\n",[70,819,821,823,825],{"class":72,"line":820},25,[70,822,479],{"class":80},[70,824,491],{"class":84},[70,826,827],{"class":80},"({ id: result.insertId, name });\n",[70,829,831],{"class":72,"line":830},26,[70,832,514],{"class":80},[70,834,836],{"class":72,"line":835},27,[70,837,838],{"class":80},"  );\n",[70,840,842],{"class":72,"line":841},28,[70,843,234],{"emptyLinePlaceholder":233},[70,845,847,849,851],{"class":72,"line":846},29,[70,848,427],{"class":80},[70,850,543],{"class":84},[70,852,546],{"class":80},[70,854,856],{"class":72,"line":855},30,[70,857,170],{"class":80},[10,859,860],{"id":860},"環境変数の設定",[15,862,863],{},"機密情報は環境変数で管理します。",[60,865,867],{"className":176,"code":866,"language":178,"meta":65,"style":65},"gcloud functions deploy myFunction \\\n  --runtime nodejs18 \\\n  --trigger-http \\\n  --set-env-vars CLOUD_SQL_CONNECTION_NAME=project:region:instance \\\n  --set-env-vars DB_USER=myuser \\\n  --set-env-vars DB_PASSWORD=mypassword \\\n  --set-env-vars DB_NAME=mydatabase\n",[67,868,869,886,896,903,913,922,931],{"__ignoreMap":65},[70,870,871,874,877,880,883],{"class":72,"line":73},[70,872,873],{"class":84},"gcloud",[70,875,876],{"class":136}," functions",[70,878,879],{"class":136}," deploy",[70,881,882],{"class":136}," myFunction",[70,884,885],{"class":76}," \\\n",[70,887,888,891,894],{"class":72,"line":114},[70,889,890],{"class":76},"  --runtime",[70,892,893],{"class":136}," nodejs18",[70,895,885],{"class":76},[70,897,898,901],{"class":72,"line":143},[70,899,900],{"class":76},"  --trigger-http",[70,902,885],{"class":76},[70,904,905,908,911],{"class":72,"line":167},[70,906,907],{"class":76},"  --set-env-vars",[70,909,910],{"class":136}," CLOUD_SQL_CONNECTION_NAME=project:region:instance",[70,912,885],{"class":76},[70,914,915,917,920],{"class":72,"line":282},[70,916,907],{"class":76},[70,918,919],{"class":136}," DB_USER=myuser",[70,921,885],{"class":76},[70,923,924,926,929],{"class":72,"line":293},[70,925,907],{"class":76},[70,927,928],{"class":136}," DB_PASSWORD=mypassword",[70,930,885],{"class":76},[70,932,933,935],{"class":72,"line":304},[70,934,907],{"class":76},[70,936,937],{"class":136}," DB_NAME=mydatabase\n",[10,939,940],{"id":940},"セキュリティのベストプラクティス",[197,942,944],{"id":943},"_1-プリペアドステートメントの使用","1. プリペアドステートメントの使用",[15,946,947],{},"SQLインジェクション対策として、必ずプリペアドステートメントを使用します。",[60,949,951],{"className":62,"code":950,"language":64,"meta":65,"style":65},"\u002F\u002F ❌ 危険: SQLインジェクションのリスク\nconnection.query(`INSERT INTO users (name) VALUES('${name}')`)\n\n\u002F\u002F ✅ 安全: プリペアドステートメント\nconnection.query('INSERT INTO users (name) VALUES (?)', [name])\n",[67,952,953,959,979,983,988],{"__ignoreMap":65},[70,954,955],{"class":72,"line":73},[70,956,958],{"class":957},"sJ8bj","\u002F\u002F ❌ 危険: SQLインジェクションのリスク\n",[70,960,961,964,966,968,971,973,976],{"class":72,"line":114},[70,962,963],{"class":80},"connection.",[70,965,430],{"class":84},[70,967,152],{"class":80},[70,969,970],{"class":136},"`INSERT INTO users (name) VALUES('${",[70,972,596],{"class":80},[70,974,975],{"class":136},"}')`",[70,977,978],{"class":80},")\n",[70,980,981],{"class":72,"line":143},[70,982,234],{"emptyLinePlaceholder":233},[70,984,985],{"class":72,"line":167},[70,986,987],{"class":957},"\u002F\u002F ✅ 安全: プリペアドステートメント\n",[70,989,990,992,994,996,999],{"class":72,"line":282},[70,991,963],{"class":80},[70,993,430],{"class":84},[70,995,152],{"class":80},[70,997,998],{"class":136},"'INSERT INTO users (name) VALUES (?)'",[70,1000,1001],{"class":80},", [name])\n",[197,1003,1005],{"id":1004},"_2-環境変数の活用","2. 環境変数の活用",[15,1007,1008],{},"データベース接続情報はコードに直接記述せず、環境変数で管理します。",[197,1010,1012],{"id":1011},"_3-cloud-sql-proxyの利用","3. Cloud SQL Proxyの利用",[15,1014,1015],{},"本番環境では、Cloud SQL Proxyを使用して安全に接続します。",[10,1017,1018],{"id":1018},"まとめ",[15,1020,1021],{},"Cloud FunctionsとCloud SQLを組み合わせることで、サーバーレスなデータベースアプリケーションを構築できます。",[15,1023,1024],{},[21,1025,1026],{},"メリット",[25,1028,1029,1032,1035],{},[28,1030,1031],{},"インフラ管理が不要",[28,1033,1034],{},"自動スケーリングで可用性向上",[28,1036,1037],{},"従量課金でコスト最適化",[15,1039,1040],{},[21,1041,1042],{},"注意点",[25,1044,1045,1048,1051],{},[28,1046,1047],{},"コールドスタート時のレイテンシ",[28,1049,1050],{},"実行時間の制限（最大540秒）",[28,1052,1053],{},"同時実行数の上限",[1055,1056,1057],"style",{},"html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":65,"searchDepth":114,"depth":114,"links":1059},[1060,1061,1062,1067,1068,1073],{"id":12,"depth":114,"text":13},{"id":54,"depth":114,"text":55},{"id":191,"depth":114,"text":192,"children":1063},[1064,1065,1066],{"id":199,"depth":143,"text":199},{"id":319,"depth":143,"text":319},{"id":554,"depth":143,"text":554},{"id":860,"depth":114,"text":860},{"id":940,"depth":114,"text":940,"children":1069},[1070,1071,1072],{"id":943,"depth":143,"text":944},{"id":1004,"depth":143,"text":1005},{"id":1011,"depth":143,"text":1012},{"id":1018,"depth":114,"text":1018},"2022-01-31","GCPのCloud Functionsを使ったサーバーレスアプリケーションの構築方法と、Cloud SQLとの連携パターンについて解説します。","md",{"tags":1078},[1079,1080,1081],"gcp","serverless","cloud-functions","\u002Fblog\u002Fcloud-functions-serverless-app",{"title":5,"description":1075},"blog\u002Fcloud-functions-serverless-app","C96i6ueDhX72R6ls8EUjga5ZrbcQoX8Tl2K0iH4PzGU",1773664054120]