1. مقدمة
أضاف الإصدار 5.0 من Springr دعمًا مخصصًا للغة Kotlin، مما يسهّل على مطوري Kotlin استخدام Spring. وبالتالي، تعني هذه التغييرات أن عمليات دمج Google Cloud التي يوفّرها Spring Cloud GCP تعمل بسلاسة أيضًا في Kotlin. في هذا الدرس التطبيقي حول الترميز، ستتعرَّف على مدى سهولة بدء استخدام خدمات Google Cloud في تطبيقات Kotlin.
يرشدك هذا الدرس التطبيقي إلى خطوات إعداد تطبيق تسجيل بسيط في Kotlin والذي يوضّح استخدام خدمات GCP، بما في ذلك: Cloud Pub/Sub وCloud SQL.
ما الذي ستقوم ببنائه
في هذا الدرس التطبيقي حول الترميز، سيتم إعداد تطبيق Kotlin Spring Boot الذي يقبل معلومات صاحب التسجيل وينشرها في موضوع Cloud Pub/Sub ويحتفظ بها في قاعدة بيانات Cloud MySQL.
المُعطيات
كيف يمكن الدمج مع خدمات Google Cloud في تطبيق Kotlin Spring.
المتطلبات
- مشروع Google Cloud Platform
- متصفح، مثل Chrome أو Firefox
كيف ستستخدم هذا البرنامج التعليمي؟
كيف تقيّم تجربتك في إنشاء تطبيقات ويب بتنسيق HTML/CSS؟
ما هو تقييمك لتجربتك في استخدام خدمات Google Cloud Platform؟
2. الإعداد والمتطلبات
إعداد بيئة ذاتية
- سجِّل الدخول إلى Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. (إذا لم يكن لديك حساب على Gmail أو G Suite، عليك إنشاء حساب.)
يُرجى تذكُّر رقم تعريف المشروع، وهو اسم فريد في جميع مشاريع Google Cloud (سبق أن تم استخدام الاسم أعلاه ولن يكون مناسبًا لك). ستتم الإشارة إليها لاحقًا في هذا الدرس التطبيقي حول الترميز باسم PROJECT_ID
.
- بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد Google Cloud.
إنّ تنفيذ هذا الدرس التطبيقي حول الترميز لن يكون مكلفًا أو مكلفًا على الإطلاق. احرص على اتّباع أي تعليمات في قسم "الحذف سريعًا". الذي يقدم لك نصائح حول كيفية إيقاف تشغيل الموارد حتى لا تتكبّد أي فواتير خارج نطاق هذا البرنامج التعليمي. يكون مستخدمو Google Cloud الجدد مؤهَّلون للانضمام إلى برنامج الفترة التجريبية المجانية التي تبلغ قيمتها 300 دولار أمريكي.
Google Cloud Shell
يمكن إدارة Google Cloud عن بُعد من الكمبيوتر المحمول، ولكن في هذا الدرس التطبيقي حول الترميز، سنستخدم Google Cloud Shell، وهي بيئة سطر أوامر يتم تشغيلها في السحابة الإلكترونية.
تفعيل Cloud Shell
- من Cloud Console، انقر على تفعيل Cloud Shell .
إذا لم يسبق لك بدء تشغيل Cloud Shell، ستظهر لك شاشة وسيطة (الجزء السفلي غير المرئي من الصفحة) تصف ماهيتها. وفي هذه الحالة، انقر على متابعة (ولن تظهر لك مرة أخرى). إليك ما تبدو عليه هذه الشاشة التي تُستخدم لمرة واحدة:
من المفترَض أن تستغرق عملية توفير المتطلبات اللازمة والاتصال بخدمة Cloud Shell بضع دقائق فقط.
يتم تحميل هذه الآلة الافتراضية مزوّدة بكل أدوات التطوير التي ستحتاج إليها. وتوفّر هذه الشبكة دليلاً رئيسيًا دائمًا بسعة 5 غيغابايت ويتم تشغيله في Google Cloud، ما يحسّن بشكل كبير من أداء الشبكة والمصادقة. يمكنك تنفيذ معظم عملك، إن لم يكن كلّه، في هذا الدرس التطبيقي حول الترميز باستخدام متصفّح أو جهاز Chromebook.
بعد الربط بخدمة Cloud Shell، من المفترَض أن يظهر لك أنّه سبق أن تمت مصادقتك وأنّ المشروع قد تم ضبطه على رقم تعريف مشروعك.
- شغِّل الأمر التالي في Cloud Shell لتأكيد مصادقتك:
gcloud auth list
مخرجات الأمر
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
gcloud config list project
مخرجات الأمر
[core] project = <PROJECT_ID>
إذا لم يكن كذلك، يمكنك تعيينه من خلال هذا الأمر:
gcloud config set project <PROJECT_ID>
مخرجات الأمر
Updated property [core/project].
3- توفير موارد النشر/الاشتراك
أولاً، سنحتاج إلى إعداد موضوع خدمة Cloud Pub/Sub والاشتراك. في هذا الطلب، سننشر معلومات التسجيل في موضوع النشر/الاشتراك. ثم تتم قراءة المعلومات من هذا الموضوع والاحتفاظ بها في قاعدة البيانات.
في هذا البرنامج التعليمي، سنعتمد على Cloud Shell لتوفير مواردنا. يُرجى العِلم أنّه يمكن للمستخدم أيضًا إعداد موارد النشر/الاشتراك من خلال قسم Cloud Pub/Sub في Google Cloud Console.
في الوحدة الطرفية في Cloud Shell، فعِّل أولاً واجهة برمجة تطبيقات Pub/Sub.
$ gcloud services enable pubsub.googleapis.com
بعد ذلك، سننشئ موضوع النشر/الاشتراك باسم registrations
لهذا التطبيق. سيتم نشر معلومات التسجيل المقدّمة من خلال الطلب في هذا الموضوع.
$ gcloud pubsub topics create registrations
أخيرًا، قم بإنشاء اشتراك للموضوع. يتيح لك الاشتراك في خدمة "النشر/الاشتراكات" تلقّي رسائل من موضوع معيّن.
$ gcloud pubsub subscriptions create registrations-sub --topic=registrations
لقد أكملت الآن إنشاء اشتراك وموضوع في Cloud Pub/Sub.
4. إنشاء مثيل وقاعدة بيانات Cloud SQL (MySQL)
بالنسبة إلى نموذج التطبيق، نحتاج أيضًا إلى إعداد مثيل قاعدة بيانات للاحتفاظ بمعلومات صاحب التسجيل. ستعتمد هذه الخطوة أيضًا على الوحدة الطرفية في Cloud Shell لتوفير موارد Cloud SQL. تجدر الإشارة إلى أنّه يمكنك عرض مثيلات Cloud SQL وضبطها من خلال Google Cloud Console أيضًا.
أولاً، عليك تفعيل واجهة برمجة التطبيقات Admin API في Cloud SQL.
$ gcloud services enable sqladmin.googleapis.com
بعد ذلك، سنوفّر مثيل Cloud SQL (MySQL). قد يستغرق تنفيذ هذا الأمر بعض الوقت.
$ gcloud sql instances create codelab-instance --region=us-east1
بعد إنشاء مثيل Cloud SQL بنجاح، أنشِئ قاعدة بيانات جديدة في المثيل باسم registrants
.
$ gcloud sql databases create registrants --instance codelab-instance
لقد أكملت الآن إعداد مثيل Cloud SQL وإعداد قاعدة البيانات لتطبيقك.
5- إعداد تطبيق Spring Boot
نحن الآن جاهزون لبدء كتابة الطلب. ستواصل الخطوات التالية استخدام Cloud Shell الموضح في خطوات الإعداد.
أولاً، سنستخدم Initializr لإنشاء رمز التجميع للمشروع. في نافذة Cloud Shell، شغِّل:
$ cd ~
$ curl https://start.spring.io/starter.tgz \
-d language=kotlin \
-d bootVersion=2.4.0 \
-d dependencies=web,data-jpa,integration,cloud-gcp-pubsub,thymeleaf \
-d baseDir=registrations-codelab | tar -xzvf -
$ cd registrations-codelab
يؤدّي هذا الأمر إلى إنشاء إعداد أوّلي لمشروع Maven بالإضافة إلى رمز تخزين لتطبيقك في دليل registrations-codelab/
. تصف الأقسام التالية تعديلات التعليمات البرمجية اللازمة لإنتاج تطبيق عامل.
محرّر رموز Cloud Shell
أسهل طريقة لبدء تعديل الرموز البرمجية وعرضها في بيئة Cloud Shell هي استخدام أداة تعديل الرموز في Cloud Shell المدمجة.
بعد فتح مثيل Cloud Shell، انقر على رمز القلم الرصاص لفتح محرِّر الرموز. ينبغي أن يسمح لك المحرر بتعديل ملفات المشروع التي تنتجها Initialzr مباشرةً.
6- تكوين قاعدة البيانات
أولاً، اضبط تطبيقك بحيث يمكنه الاتصال بقاعدة بيانات Cloud MySQL التي أعددتها. توفّر مكتبات Spring Cloud GCP إجراء تفعيل Cloud MySQL الذي يوفر الاعتماديات اللازمة للاتصال بمثيل Cloud MySQL.
أضِف تبعية spring-cloud-gcp-starter-sql-mysql
إلى المشروع pom.xml:
registrations-codelab/pom.xml
... <dependencies> ... Other dependencies above ... <!-- Add the MySQL starter to the list of dependencies --> <dependency> <groupId>com.google.cloud</groupId> <artifactId>spring-cloud-gcp-starter-sql-mysql</artifactId> </dependency> </dependencies>
بالإضافة إلى ذلك، يجب تعديل ملف الإعداد application.properties
لوصف إعدادات قاعدة البيانات. انسخ السمات التالية إلى ملف application.properties
.
ابحث عن اسم اتصال المثيل بقاعدة البيانات:
$ gcloud sql instances describe codelab-instance \ --format 'value(connectionName)'
وسيتم استخدام ناتج هذا في ملف application.properties
لضبط معلومات الاتصال.
src/main/resources/application.properties
# Modify this property using the output from the previous command line. spring.cloud.gcp.sql.instance-connection-name=INSTANCE_CONNECTION_NAME # Your database name spring.cloud.gcp.sql.database-name=registrants # So app starts despite "table already exists" errors. spring.datasource.continue-on-error=true # Enforces database initialization spring.datasource.initialization-mode=always # Cloud SQL (MySQL) only supports InnoDB, not MyISAM spring.jpa.database-platform=org.hibernate.dialect.MySQL55Dialect spring.jpa.hibernate.ddl-auto=create-drop # This is used if you want to connect to a different database instance # user other than root; not used in codelab. # spring.datasource.username=root # This is used to specify the password of the database user; # not used in codelab. # spring.datasource.password=password
الخاصية الوحيدة التي يجب تعديلها هي اسم اتصال المثيل. يجب تنسيق هذه القيمة كقيمة مفصولة بنقطتين بالتنسيق: YOUR_GCP_PROJECT_ID:REGION:DATABASE_INSTANCE_NAME
.
7. إنشاء المحتوى الثابت
أولاً، سننشئ الواجهة الأمامية لتطبيقنا. يجب أن يحتوي الطلب على نموذج يتيح لشخص ما تسجيل الأفراد، وكذلك طريقة عرض تعرض جميع المسجلين الناجحين.
بالنسبة إلى الصفحة الرئيسية، أنشئ index.html
يحتوي على نموذج التسجيل.
src/main/resources/static/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Registration Sample Application</title>
</head>
<body>
<h1>Registration</h1>
<div>
<nav>
<a href="/">Home</a><br>
<a href="/registrants">Registered People</a><br>
</nav>
<p>
This is a demo registration application which sends user information to a Pub/Sub topic and
persists it into a MySQL database.
</p>
<h2>Register Person</h2>
<div>
<form action="/registerPerson" method="post">
First Name: <input type="text" name="firstName" />
Last Name: <input type="text" name="lastName" />
Email: <input type="text" name="email" />
<input type="submit" value="Submit"/>
</form>
</div>
</div>
</body>
</html>
بعد ذلك، سننشئ نموذج Thymeleaf باسم registrants.html
لعرض المستخدمين المسجَّلين. Thymeleaf هو إطار عمل نماذج نستخدمه لإنشاء وعرض محتوى HTML تم إنشاؤه ديناميكيًا. سترى أن النموذج يبدو مثل HTML، باستثناء أنّه يحتوي على بعض عناصر Markdown الإضافية للتعامل مع المحتوى الديناميكي. يقبل هذا النموذج مَعلمة واحدة باسم personsList
تحتوي على جميع أصحاب التسجيل الذين تم تسجيلهم من خلال التطبيق.
src/main/resources/templates/registrants.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Registrants List</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<h1>Registrants List</h1>
<p>
This page displays all the people who were registered through the Pub/Sub topic.
All results are retrieved from the MySQL database.
</p>
<table border="1">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
</tr>
<tr th:each="person : ${personsList}">
<td>[[${person.firstName}]]</td>
<td>[[${person.lastName}]]</td>
<td>[[${person.email}]]</td>
</tr>
</table>
</body>
</html>
في هذه المرحلة، يمكنك التحقّق من عرض المحتوى الثابت.
إنشاء التطبيق وتشغيله باستخدام Maven:
$ ./mvnw spring-boot:run
انقر على زر المعاينة في نافذة Cloud Shell وتحقَّق من ظهور الصفحة الرئيسية. لن تعمل أي من الوظائف على واجهة المستخدم لأننا نفتقد وحدة تحكم الويب. ستتم إضافة هذه المعلومات في الخطوة التالية.
بعد معاينة التطبيق، اضغط على CTRL+C
لإنهاء التطبيق.
8. إرسال المسجلين إلى موضوع نشر/اشتراك
في هذه الخطوة، سنطبّق الميزة التي تتيح نشر المسجّلين الذين تم إرسالهم من خلال نموذج الويب في موضوع Cloud Pub/Sub.
إضافة فئات البيانات
أولاً، سنقوم بإنشاء بعض فئات بيانات Kotlin، ستكون هذه الجهات بمثابة كيانات JPA وتعمل أيضًا كتمثيل وسيط للمسجّلين الذين تم إرسالهم من خلال النموذج.
في حزمة الإصدار التجريبي، أضِف ملفَين جديدَين: فئة Person
وفئة بيانات Spring PersonRepository
. تتيح لنا هاتان الفئتان تخزين إدخالات التسجيل واستردادها بسهولة من قاعدة بيانات MySQL باستخدام Spring Data JPA.
src/main/kotlin/com/example/demo/Person.kt
package com.example.demo
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id
@Entity
data class Person(
val firstName: String,
val lastName: String,
val email: String,
@Id @GeneratedValue
var id: Long? = 0)
src/main/kotlin/com/example/demo/PersonRepository.kt
package com.example.demo
import org.springframework.data.repository.CrudRepository
interface PersonRepository : CrudRepository<Person, Long>
إضافة Web Controller
بعد ذلك، سننشئ فئة مسؤول التحكّم بالبيانات تعالج أصحاب التسجيل من النموذج وترسل المعلومات إلى موضوع Cloud Pub/Sub الذي أنشأته سابقًا. تنشئ وحدة التحكّم هذه نقطتَي نهاية:
/registerPerson
: نقطة نهاية POST التي يتم فيها إرسال معلومات صاحب التسجيل ثم إرسالها إلى موضوع النشر/الاشتراك. في دالةregisterPerson(..)
، يتم إرسال معلومات صاحب التسجيل إلى موضوع النشر/الاشتراك باستخدامPubSubTemplate
، وهي فئة ملائمة من عمليات دمج خدمة النشر/الاشتراك في Cloud Cloud Platform في Spring Cloud التي تقلّل الرمز النموذجي المطلوب لبدء التفاعل مع Cloud Pub/Sub./registrants
: يعرض هذا الخيار جميع المستخدمين المسجّلين بنجاح في قاعدة البيانات. تم استرداد هذه المعلومات من مثيل MySQL باستخدام مستودع بيانات Spring الذي أنشأناه في الخطوة السابقة.
أنشئ فئة وحدة التحكم التالية في الحزمة التجريبية:
src/main/kotlin/com/example/demo/Controller.kt
package com.example.demo
import com.google.cloud.spring.pubsub.core.PubSubTemplate
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.servlet.ModelAndView
import org.springframework.web.servlet.view.RedirectView
@RestController
class Controller(val pubSubTemplate: PubSubTemplate, val personRepository: PersonRepository) {
// The Pub/Sub topic name created earlier.
val REGISTRATION_TOPIC = "registrations"
@PostMapping("/registerPerson")
fun registerPerson(
@RequestParam("firstName") firstName: String,
@RequestParam("lastName") lastName: String,
@RequestParam("email") email: String): RedirectView {
pubSubTemplate.publish(
REGISTRATION_TOPIC,
Person(firstName, lastName, email))
return RedirectView("/")
}
@GetMapping("/registrants")
fun getRegistrants(): ModelAndView {
val personsList = personRepository.findAll().toList()
return ModelAndView("registrants", mapOf("personsList" to personsList))
}
}
يقرأ مسؤول التحكّم معلومات صاحب التسجيل المرسَلة من خلال نموذج الويب، ثم ينشر المعلومات في موضوع النشر/الاشتراك.
إضافة أداة خرائط لكائنات JSON
ربما لاحظت في وحدة التحكّم أننا ننشر كائن Person
لموضوع النشر/الاشتراك وليس لسلسلة. هذا ممكن لأنّنا نستفيد من دعم Spring Cloud GCP في إرسال حمولات JSON المخصصة إلى المواضيع، حيث تتيح لك المكتبات تسلسل العناصر إلى JSON، وإرسال حمولات JSON إلى أحد المواضيع وإلغاء تسلسل حمولة البيانات عند استلامها.
للاستفادة من هذه الميزة، يجب أن نضيف علامة ObjectMapper
إلى سياق تطبيقك. سيتم استخدام حبوب ObjectMapper
هذه لإنشاء تسلسل بين العناصر من وإلى JSON عندما يرسل تطبيقك الرسائل ويستلمها. في الفئة DemoApplication.kt
، أضف JacksonPubSubMessageConverter
حبوب البن:
src/main/kotlin/com/example/demo/DemoApplication.kt
package com.example.demo
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
// new imports to add
import org.springframework.context.annotation.Bean
import com.fasterxml.jackson.databind.ObjectMapper
import com.google.cloud.spring.pubsub.support.converter.JacksonPubSubMessageConverter
@SpringBootApplication
class DemoApplication {
// This bean enables serialization/deserialization of
// Java objects to JSON for Pub/Sub payloads
@Bean
fun jacksonPubSubMessageConverter(objectMapper: ObjectMapper) =
JacksonPubSubMessageConverter(objectMapper)
}
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
عند هذه النقطة، يمكنك محاولة تشغيل التطبيق مرة أخرى عن طريق تشغيل:
$ ./mvnw spring-boot:run
من نموذج الويب على الصفحة الرئيسية، سيرسل التطبيق الآن المعلومات إلى موضوع النشر/الاشتراك الذي أنشأته. مع ذلك، لا يزال الفيديو غير مفيد لأنّنا ما زلنا بحاجة إلى القراءة من موضوع النشر/الاشتراك. يتم تحقيق ذلك في الخطوة التالية.
9. قراءة بيانات المسجّلين من خلال موضوع النشر/الاشتراك
في الخطوة الأخيرة، سنعالج معلومات صاحب التسجيل من موضوع النشر/الاشتراك ونواصل حفظ المعلومات في قاعدة بيانات Cloud MySQL. سيؤدي هذا الإجراء إلى إكمال طلب الانضمام، ما يتيح لك إرسال مستخدمين مسجَّلين جدد من خلال النموذج وعرض جميع المستخدمين المسجَّلين من خلال نقطة نهاية /registrants
.
سيتمكن هذا التطبيق من الاستفادة من Spring Integration، والتي توفر العديد من التجريدات المناسبة للتعامل مع الرسائل. سنضيف PubSubInboundChannelAdapter
لنتمكّن من قراءة الرسائل من موضوع النشر/الاشتراك ووضعها في pubsubInputChannel
لإجراء مزيد من المعالجة. بعد ذلك، سيتم ضبط الدالة messageReceiver
باستخدام @ServiceActivator
ليتم استدعاؤها مع الرسائل التي تصل إلى pubsubInputChannel
.
src/main/kotlin/com/example/demo/DemoApplication.kt
package com.example.demo
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Bean
import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.cloud.gcp.pubsub.support.converter.JacksonPubSubMessageConverter
// new imports to add
import com.google.cloud.spring.pubsub.core.PubSubTemplate
import com.google.cloud.spring.pubsub.integration.AckMode
import com.google.cloud.spring.pubsub.integration.inbound.PubSubInboundChannelAdapter
import com.google.cloud.spring.pubsub.support.BasicAcknowledgeablePubsubMessage
import com.google.cloud.spring.pubsub.support.GcpPubSubHeaders
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.integration.annotation.ServiceActivator
import org.springframework.integration.channel.DirectChannel
import org.springframework.messaging.MessageChannel
import org.springframework.messaging.handler.annotation.Header
@SpringBootApplication
class DemoApplication {
private val REGISTRANT_SUBSCRIPTION = "registrations-sub"
@Autowired
private lateinit var personRepository: PersonRepository
// New Spring Beans to add
@Bean
fun pubsubInputChannel() = DirectChannel()
@Bean
fun messageChannelAdapter(
@Qualifier("pubsubInputChannel") inputChannel: MessageChannel,
pubSubTemplate: PubSubTemplate): PubSubInboundChannelAdapter {
val adapter = PubSubInboundChannelAdapter(
pubSubTemplate, REGISTRANT_SUBSCRIPTION)
adapter.outputChannel = inputChannel
adapter.ackMode = AckMode.MANUAL
adapter.payloadType = Person::class.java
return adapter
}
@ServiceActivator(inputChannel = "pubsubInputChannel")
fun messageReceiver(
payload: Person,
@Header(GcpPubSubHeaders.ORIGINAL_MESSAGE) message: BasicAcknowledgeablePubsubMessage) {
personRepository.save(payload)
print("Message arrived! Payload: $payload")
message.ack()
}
// ObjectMapper bean from previous step
@Bean
fun jacksonPubSubMessageConverter(objectMapper: ObjectMapper) = JacksonPubSubMessageConverter(objectMapper)
}
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
في هذه المرحلة، تكون قد أكملت إعداد التطبيق. للتأكّد من عمل التطبيق بشكل صحيح، شغِّل:
$ ./mvnw spring-boot:run
انقر على الزر معاينة مرة أخرى وحاول تسجيل مستخدم من خلال ملء النموذج وإرساله.
انقر على رابط الأشخاص المسجَّلون للتحقق من ظهور صاحب التسجيل الجديد في الجدول.
تهانينا، لقد انتهيت الآن! أنهِ التطبيق بالضغط على CTRL+C
في النافذة الطرفية.
10. تنظيف
لتنظيف البيئة، عليك حذف موضوع Pub/Sub ومثيل Cloud MySQL الذي أنشأته.
حذف مثيل Cloud MySQL
$ gcloud sql instances delete codelab-instance
حذف مراجع النشر/الاشتراك
$ gcloud pubsub subscriptions delete registrations-sub $ gcloud pubsub topics delete registrations
11. تهانينا!
لقد أكملت الآن كتابة تطبيق Spring Kotlin الذي يتكامل مع Cloud Pub/Sub وCloud SQL (MySQL).
مزيد من المعلومات
- بدء مشروع Google Cloud Platform: http://cloud.spring.io/spring-cloud-gcp/
- الانتقال إلى مستودع GitHub في Google Cloud Platform: https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- Java على Google Cloud Platform: https://cloud.google.com/java/
- أمثلة على تطبيقات Kotlin باستخدام GCP: https://github.com/GoogleCloudPlatform/spring-cloud-gcp/tree/master/spring-cloud-gcp-kotlin-samples
الترخيص
هذا العمل مرخّص بموجب رخصة المشاع الإبداعي 2.0 مع نسب العمل إلى مؤلف عام.