hello! Hari ini kami akan menambah langganan kepada kumpulan artikel dalam JavaRush. Ini sepadan dengan
isu JRTB-5 pada GitHub. Biar saya jelaskan: JavaRush mempunyai bahagian
yang dipanggil Artikel , dan di dalamnya terdapat
Kumpulan Artikel. Ideanya adalah untuk menerima pemberitahuan tentang artikel baharu daripada satu atau lebih kumpulan melalui bot telegram.
Tambah JRTB-5
Katakan saya berminat dengan artikel daripada kumpulan
Kisah Kejayaan . Oleh itu, saya ingin melanggan kemas kini daripada kumpulan ini dan menerima pautan ke penerbitan baharu setiap kali. Sebagai sebahagian daripada tugas ini, kita perlu belajar cara menggunakan API terbuka untuk bekerja dengan kumpulan dalam JavaRush. Hanya pada masa ini perkara seperti itu tiba. Berikut ialah
pautan kepada perihalan API terbuka .
Kawan-kawan! Adakah anda ingin mengetahui dengan segera apabila kod baharu untuk projek atau artikel baharu dikeluarkan? Sertai saluran tg saya . Di sana saya mengumpulkan artikel, pemikiran dan pembangunan sumber terbuka saya bersama-sama. |
Apa itu swagger? Mari kita fikirkan sekarang
Kami belum bercakap tentang kesombongan lagi. Bagi mereka yang tidak tahu, saya akan menerangkan secara ringkas: ini adalah tempat di mana anda boleh melihat secara terbuka pada API pelayan dan cuba membuat beberapa permintaan kepadanya. Biasanya, seorang yang sombong mengumpulkan permintaan yang mungkin. Dalam kes kami, terdapat tiga kumpulan:
forum-question ,
group ,
post . Dalam setiap kumpulan akan ada satu atau lebih permintaan yang menunjukkan semua data yang diperlukan untuk membina permintaan ini (iaitu, apakah parameter tambahan yang boleh diluluskan, apa yang perlu dilakukan dengan mereka, kaedah http apa, dan sebagainya). Saya menasihati anda untuk membaca dan menonton lebih lanjut mengenai topik ini, kerana ini adalah bahagian pembangunan yang hampir setiap daripada anda akan hadapi. Untuk mengetahuinya, mari kita ketahui berapa banyak kumpulan yang terdapat dalam JavaRush. Untuk melakukan ini, kembangkan kumpulan pengawal kumpulan dan pilih Dapatkan permintaan
/api/1.0/rest/groups/count . Ia akan mengembalikan kepada kami bilangan kumpulan dalam JavaRush. Mari lihat:
Imej menunjukkan bahawa pertanyaan ini menyokong beberapa parameter (pertanyaan, jenis, penapis). Untuk mencuba permintaan ini, anda perlu mencari butang
Try it out , selepas itu parameter ini boleh dikonfigurasikan:
Anda juga boleh mengkonfigurasi jenis, penapis dan pertanyaan di sana (ia sebenarnya menarik di sini: ini akan menjadi carian teks dalam kumpulan). Tetapi buat masa ini, mari jalankannya tanpa sebarang sekatan dan lihat berapa banyak kumpulan yang terdapat dalam JavaRush. Untuk melakukan ini, klik pada Laksanakan. Di bawahnya akan ada respons (dalam bahagian Respons Pelayan) untuk permintaan ini:
Kami melihat bahawa terdapat
30 kumpulan secara keseluruhan , permintaan ini telah diselesaikan dalam 95ms dan terdapat satu set beberapa pengepala dalam respons. Seterusnya, mari cuba untuk mengkonfigurasi beberapa parameter. Mari pilih parameter jenis yang sama dengan nilai SYARIKAT dan lihat bagaimana keputusan berubah:
Terdapat 4 daripadanya. Bagaimana untuk menyemak ini? Mudah sahaja: anda boleh pergi ke tapak web, cari bahagian artikel, pilih semua kumpulan dan tambah penapis yang sesuai di sana (
https://javarush.com/groups/all?type=COMPANY ). Dan ya, memang ada 4 sahaja. Walaupun sebenarnya ada tiga :D
Setakat ini ia sesuai. By the way, kalau kita semak universiti, belum ada lagi. Hanya untuk keseronokan, lihat apa yang berlaku jika anda menetapkan penapis = MY dalam penyemak imbas di mana anda log masuk ke Javarush dan tidak log masuk. Lebih lanjut mengenai kesombongan - dalam
artikel tentang Habré ini .
Menulis pelanggan untuk Javarush API untuk kumpulan
Kini, berdasarkan API terbuka, kami akan menulis klien Java yang boleh membuat permintaan, menerima respons dan mengetahui dengan tepat objek yang akan tiba. Kami juga akan mengambil objek dari kesombongan, dari bahagian
Model (di bahagian paling bawah halaman). Mari buat pakej baharu dan panggil ia javarushclient di sebelah perkhidmatan, repositori. Pada masa hadapan, kami akan memindahkannya ke perpustakaan berasingan dalam organisasi Komuniti Javarush dan akan menggunakannya secara eksklusif sebagai pergantungan.
Pertama sekali, anda perlu menambah Unitrest, perpustakaan untuk membuat permintaan http ke API JavaRush:
<dependency>
<groupId>com.konghq</groupId>
<artifactId>unirest-java</artifactId>
<version>${unirest.version}</version>
</dependency>
Dan letakkan versi dalam blok sifat:
<unirest.version>3.11.01</unirest.version>
Sebaik sahaja kami mempunyai pergantungan, kami boleh mula menambah kod. Mari buat klien untuk kumpulan JavaRushGroupClient dan pelaksanaan dalam kelas JavaRushGroupClientImpl. Tetapi pertama-tama anda perlu membuat DTO (objek pemindahan data) - iaitu, kelas yang objeknya akan membawa semua data yang diperlukan untuk pelanggan. Semua model boleh dilihat dalam kesombongan. Di bahagian paling bawah terdapat bahagian
Model , di mana anda boleh mengiranya. Beginilah rupa
GroupDiscussionInfo dalam swagger: Dalam pakej javarushclient, kami akan mencipta
pakej
dto , yang mana kami akan menambah, berdasarkan data dari swagger, kelas berikut:
-
MeGroupInfoStatus :
package com.github.javarushcommunity.jrtb.javarushclient.dto;
public enum MeGroupInfoStatus {
UNKNOWN, CANDIDATE, INVITEE, MEMBER, EDITOR, MODERATOR, ADMINISTRATOR, BANNED
}
-
MeGroupInfo :
package com.github.javarushcommunity.jrtb.javarushclient.dto;
import lombok.Data;
@Data
public class MeGroupInfo {
private MeGroupInfoStatus status;
private Integer userGroupId;
}
-
GroupInfoType :
package com.github.javarushcommunity.jrtb.javarushclient.dto;
public enum GroupInfoType {
UNKNOWN, CITY, COMPANY, COLLEGE, TECH, SPECIAL, COUNTRY
}
-
Maklumat Perbincangan Pengguna :
package com.github.javarushcommunity.jrtb.javarushclient.dto;
import lombok.Data;
@Data
public class UserDiscussionInfo {
private Boolean isBookmarked;
private Integer lastTime;
private Integer newCommentsCount;
}
-
GroupVisibilitysdtatus :
package com.github.javarushcommunity.jrtb.javarushclient.dto;
public enum GroupVisibilityStatus {
UNKNOWN, RESTRICTED, PUBLIC, PROTECTED, PRIVATE, DISABLED, DELETED
}
-
Kemudian - GroupInfo :
package com.github.javarushcommunity.jrtb.javarushclient.dto;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class GroupInfo {
private Integer id;
private String avatarUrl;
private String createTime;
private String description;
private String key;
private Integer levelToEditor;
private MeGroupInfo meGroupInfo;
private String pictureUrl;
private String title;
private GroupInfoType type;
private Integer userCount;
private GroupVisibilityStatus visibilityStatus;
}
Memandangkan
GroupInfo dan
GroupDiscussionInfo hampir sama sepenuhnya, mari kita hubungkan mereka dalam warisan -
GroupDiscusionInfo :
package com.github.javarushcommunity.jrtb.javarushclient.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@EqualsAndHashCode(callSuper = true)
@Data
@ToString(callSuper = true)
public class GroupDiscussionInfo extends GroupInfo {
private UserDiscussionInfo userDiscussionInfo;
private Integer commentsCount;
}
Kami juga memerlukan penapis untuk permintaan
GroupFilter :
package com.github.javarushcommunity.jrtb.javarushclient.dto;
public enum GroupFilter {
UNKNOWN, MY, ALL
}
Dalam permintaan untuk mendapatkan melalui ID, ia mengembalikan GroupDiscussionInfo dan dalam permintaan untuk koleksi kumpulan, anda boleh mendapatkan kedua-dua GroupInfo dan GroupDiscussionInfo. Memandangkan permintaan boleh mempunyai jenis, pertanyaan, penapis, mengimbangi dan had, mari buat kelas
GroupRequestArgs yang berasingan dan jadikan ia kelas pembina (baca apakah corak pembina):
package com.github.javarushcommunity.jrtb.javarushclient.dto;
import lombok.*;
import java.util.HashMap;
import java.util.Map;
import static java.util.Objects.nonNull;
@Builder
@Getter
public class GroupRequestArgs {
private final String query;
private final GroupInfoType type;
private final GroupFilter filter;
private final Integer offset;
private final Integer limit;
public Map populateQueries() {
Map queries = new HashMap<>();
if(nonNull(query)) {
queries.put("query", query);
}
if(nonNull(type)) {
queries.put("type", type);
}
if(nonNull(filter)) {
queries.put("filter", filter);
}
if(nonNull(offset)) {
queries.put("offset", offset);
}
if(nonNull(limit)) {
queries.put("limit", limit);
}
return queries;
}
}
Untuk mencari bilangan kumpulan, ia sedikit berbeza. Ia hanya mempunyai pertanyaan, jenis dan penapis. Dan nampaknya anda tidak mahu menduplikasi kod tersebut. Pada masa yang sama, jika anda mula menggabungkannya, ternyata hodoh apabila bekerja dengan pembina. Jadi saya memutuskan untuk memisahkannya dan mengulangi kod tersebut. Inilah rupa
GroupCountRequestArgs :
package com.github.javarushcommunity.jrtb.javarushclient.dto;
import lombok.Builder;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
import static java.util.Objects.nonNull;
@Builder
@Getter
public class GroupsCountRequestArgs {
private final String query;
private final GroupInfoType type;
private final GroupFilter filter;
public Map populateQueries() {
Map queries = new HashMap<>();
if (nonNull(query)) {
queries.put("query", query);
}
if (nonNull(type)) {
queries.put("type", type);
}
if (nonNull(filter)) {
queries.put("filter", filter);
}
return queries;
}
}
Ya, saya tidak menyebut bahawa dua kelas terakhir mempunyai kaedah populateQueries, yang akan menyediakan peta untuk membuat pertanyaan (anda akan melihatnya kemudian). Berdasarkan kelas yang diterangkan di atas, mari buat antara muka untuk
JavaRushGroupClient :
package com.github.javarushcommunity.jrtb.javarushclient;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupInfo;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupRequestArgs;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupsCountRequestArgs;
import java.util.List;
public interface JavaRushGroupClient {
List<GroupInfo> getGroupList(GroupRequestArgs requestArgs);
List<GroupDiscussionInfo> getGroupDiscussionList(GroupRequestArgs requestArgs);
Integer getGroupCount(GroupsCountRequestArgs countRequestArgs);
GroupDiscussionInfo getGroupById(Integer id);
}
Dua permintaan berbeza untuk kes apabila kami ingin mendapatkan maklumat GroupInfo atau GroupDiscussionInfo ditambah. Jika tidak, permintaan ini adalah sama, dan satu-satunya perbezaan adalah bahawa dalam satu bendera includeDiscussion akan menjadi benar, dan dalam satu lagi ia akan palsu. Oleh itu, terdapat 4 kaedah, bukan tiga. Sekarang mari kita mula melaksanakan:
package com.github.javarushcommunity.jrtb.javarushclient;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupInfo;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupRequestArgs;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupsCountRequestArgs;
import kong.unirest.GenericType;
import kong.unirest.Unirest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class JavaRushGroupClientImpl implements JavaRushGroupClient {
private final String javarushApiGroupPath;
public JavaRushGroupClientImpl(@Value("${javarush.api.path}") String javarushApi) {
this.javarushApiGroupPath = javarushApi + "/groups";
}
@Override
public List<GroupInfo> getGroupList(GroupRequestArgs requestArgs) {
return Unirest.get(javarushApiGroupPath)
.queryString(requestArgs.populateQueries())
.asObject(new GenericType<list<GroupInfo>>() {
})
.getBody();
}
@Override
public List<GroupDiscussionInfo> getGroupDiscussionList(GroupRequestArgs requestArgs) {
return Unirest.get(javarushApiGroupPath)
.queryString(requestArgs.populateQueries())
.asObject(new GenericType<list<GroupDiscussionInfo>>() {
})
.getBody();
}
@Override
public Integer getGroupCount(GroupsCountRequestArgs countRequestArgs) {
return Integer.valueOf(
Unirest.get(String.format("%s/count", javarushApiGroupPath))
.queryString(countRequestArgs.populateQueries())
.asString()
.getBody()
);
}
@Override
public GroupDiscussionInfo getGroupById(Integer id) {
return Unirest.get(String.format("%s/group%s", javarushApiGroupPath, id.toString()))
.asObject(GroupDiscussionInfo.class)
.getBody();
}
}
Saya menambah laluan ke API dalam pembina menggunakan anotasi Nilai yang sudah biasa. Ini menunjukkan bahawa nilai dalam anotasi sepadan dengan medan dalam fail sifat. Oleh itu, mari tambah baris baharu pada application.properties:
javarush.api.path=https://javarush.com/api/1.0/rest
Nilai ini kini akan berada di satu tempat untuk semua klien API, dan jika laluan API berubah, kami akan mengemas kininya dengan cepat. Sebelum ini, saya
memalu paku dengan mikroskop, menerima respons daripada permintaan http melalui Unirest, menterjemahkannya ke dalam rentetan dan kemudian menghuraikan rentetan ini melalui Jackson... Ia menakutkan, membosankan dan memerlukan banyak perkara tambahan. Di
perpustakaan ini anda boleh melihat rupanya. Sebaik sahaja saya mendapatkannya, saya akan memfaktorkan semula segala-galanya.
Sesiapa sahaja yang ingin mencuba mengemas kini perpustakaan ini - tambah objek penerima hanya menggunakan alatan perpustakaan unirest - tulis dalam mesej peribadi atau sebagai isu baharu dalam perpustakaan itu sendiri. Ini akan menjadi pengalaman kerja sebenar untuk anda, tetapi saya tidak kisah. Saya akan menjalankan semakan kod penuh dan bantuan jika perlu. |
Sekarang persoalannya ialah: adakah kod kami berfungsi seperti yang kami harapkan? Jawapannya mudah: anda hanya perlu menulis ujian untuk mereka. Seperti yang saya katakan lebih daripada sekali, pembangun mesti boleh menulis ujian. Oleh itu, menggunakan UI Swagger kami, kami akan menghantar permintaan, melihat respons dan menggantikannya ke dalam ujian sebagai hasil yang dijangkakan. Anda mungkin menyedari dengan segera bahawa bilangan kumpulan tidak statik dan boleh berubah. Dan awak betul. Satu-satunya soalan ialah berapa kerap nombor ini berubah? Sangat jarang, jadi dalam tempoh beberapa bulan kita boleh mengatakan bahawa nilai ini akan menjadi statik. Dan jika sesuatu berubah, kami akan mengemas kini ujian. Bertemu - JavaRushGroupClientTest:
package com.github.javarushcommunity.jrtb.javarushclient;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupDiscussionInfo;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupInfo;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupRequestArgs;
import com.github.javarushcommunity.jrtb.javarushclient.dto.GroupsCountRequestArgs;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
import static com.github.javarushcommunity.jrtb.javarushclient.dto.GroupInfoType.TECH;
@DisplayName("Integration-level testing for JavaRushGroupClientImplTest")
class JavaRushGroupClientTest {
private final JavaRushGroupClient groupClient = new JavaRushGroupClientImpl("https://javarush.com/api/1.0/rest");
@Test
public void shouldProperlyGetGroupsWithEmptyArgs() {
GroupRequestArgs args = GroupRequestArgs.builder().build();
List<GroupInfo> groupList = groupClient.getGroupList(args);
Assertions.assertNotNull(groupList);
Assertions.assertFalse(groupList.isEmpty());
}
@Test
public void shouldProperlyGetWithOffSetAndLimit() {
GroupRequestArgs args = GroupRequestArgs.builder()
.offset(1)
.limit(3)
.build();
List<GroupInfo> groupList = groupClient.getGroupList(args);
Assertions.assertNotNull(groupList);
Assertions.assertEquals(3, groupList.size());
}
@Test
public void shouldProperlyGetGroupsDiscWithEmptyArgs() {
GroupRequestArgs args = GroupRequestArgs.builder().build();
List<GroupDiscussionInfo> groupList = groupClient.getGroupDiscussionList(args);
Assertions.assertNotNull(groupList);
Assertions.assertFalse(groupList.isEmpty());
}
@Test
public void shouldProperlyGetGroupDiscWithOffSetAndLimit() {
GroupRequestArgs args = GroupRequestArgs.builder()
.offset(1)
.limit(3)
.build();
List<GroupDiscussionInfo> groupList = groupClient.getGroupDiscussionList(args);
Assertions.assertNotNull(groupList);
Assertions.assertEquals(3, groupList.size());
}
@Test
public void shouldProperlyGetGroupCount() {
GroupsCountRequestArgs args = GroupsCountRequestArgs.builder().build();
Integer groupCount = groupClient.getGroupCount(args);
Assertions.assertEquals(30, groupCount);
}
@Test
public void shouldProperlyGetGroupTECHCount() {
GroupsCountRequestArgs args = GroupsCountRequestArgs.builder()
.type(TECH)
.build();
Integer groupCount = groupClient.getGroupCount(args);
Assertions.assertEquals(7, groupCount);
}
@Test
public void shouldProperlyGetGroupById() {
Integer androidGroupId = 16;
GroupDiscussionInfo groupById = groupClient.getGroupById(androidGroupId);
Assertions.assertNotNull(groupById);
Assertions.assertEquals(16, groupById.getId());
Assertions.assertEquals(TECH, groupById.getType());
Assertions.assertEquals("android", groupById.getKey());
}
}
Ujian ditulis dalam gaya yang sama seperti sebelum ini. Terdapat beberapa ujian untuk setiap permintaan. Tidak ada gunanya menguji segala-galanya, kerana saya berpendapat bahawa API ini telah pun diuji dengan cara yang terbaik.
Kesimpulan
Sebagai sebahagian daripada artikel ini, kami menambahkan klien Java untuk kumpulan pada API JavaRush. Seperti yang mereka katakan, hidup dan belajar. Semasa saya menulis pelanggan ini, saya mengambil kesempatan daripada dokumentasi mereka dan dengan mudah menggunakan kerja dengan objek yang mereka sediakan. Saya menarik perhatian anda kepada tugas yang saya cadangkan. Jika sesiapa berminat, tulis mesej peribadi kepada saya, saya lebih pasti bahawa ia akan menjadi pengalaman yang sangat menarik. Ini adalah bahagian pertama. Dalam yang kedua, kami akan melaksanakan secara langsung arahan menambah dan (jika kami memasukkannya ke dalam satu artikel) kami akan menambah mendapatkan senarai kumpulan yang dilanggan oleh pengguna. Seterusnya, sesiapa yang mempunyai keinginan dan bakat untuk menulis teks untuk bot, sila tulis kepada saya dalam PM. Saya bukan pakar dalam perkara ini dan sebarang bantuan akan sangat membantu. Mari kita rasmikan semua ini sebagai pembangunan sumber terbuka, ia akan menjadi menarik! Baiklah, seperti biasa -
suka, langgan, loceng , berikan
projek kami bintang , tulis komen dan nilaikan artikel itu!
GO TO FULL VERSION