372 čitanja
372 čitanja

Kako brzo predstaviti novi API koristeći Spring Boot i Gradle

po John Vester14m2025/03/24
Read on Terminal Reader

Predugo; Čitati

Vrijeme izlaska na tržište može donijeti ili uništiti svaku ideju ili rješenje. Provjerite koliko se brzo RESTful API može stvoriti korištenjem ChatGPT-a, Spring Boot-a, Gradle-a i Heroku-a.
featured image - Kako brzo predstaviti novi API koristeći Spring Boot i Gradle
John Vester HackerNoon profile picture
0-item
1-item
2-item


Posljednjih pet godina na zidu ureda imam citat “sve počinje idejom”.


Moja je supruga pronašla ovaj proizvod na Etsyju ubrzo nakon što sam počeo razvijati kolekciju API-ja za aplikaciju za fitness. Volim ovu izjavu jer bilježi strast koja me obuzima tijekom faza stvaranja novog projekta. Ovo mi je još uvijek najdraži aspekt inženjerstva, čak i nakon tri desetljeća moje karijere.


Ono što sam naučio tijekom ovog vremena jest da je ideja važna samo ako je netko ima priliku iskusiti. Ako nekoj ideji treba predugo da postane stvarnost, završit ćete s propuštenom prilikom jer vas netko drugi pobijedi. Zbog toga se startupi uvijek utrkuju kako bi svoje ideje što prije plasirali na tržište.


Pogledajmo kako ideju možemo pretvoriti u stvarnost… brzo.

Pretpostavke

U ovom ćemo članku stvari pojednostaviti. Koristit ćemo Javu 17 i Spring Boot 3 za izradu RESTful API-ja. U ovom primjeru koristit ćemo Gradle za našu automatizaciju izgradnje.


Dok bi ideja usluge koju planiramo plasirati na tržište obično koristila sloj postojanosti, ostavit ćemo to po strani za ovaj primjer i statički definirati naše podatke unutar klase repozitorija.


Nećemo brinuti o dodavanju bilo kakve sigurnosti za ovaj primjer, jednostavno dopuštamo anonimni pristup za ovaj dokaz koncepta.

API za motivacijske citate

Pretpostavimo da je naša ideja API za motivacijske citate. Kako bismo bili sigurni da jurimo što je brže moguće, zamolio sam ChatGPT da za mene izradi OpenAPI specifikaciju.


Za nekoliko sekundi ChatGPT je dao odgovor:


Ovo je OpenAPI specifikacija, u YAML-u, koju je ChatGPT generirao:


 openapi: 3.0.0 info: title: Motivational Quotes API description: An API that provides motivational quotes. version: 1.0.0 servers: - url: https://api.example.com description: Production server paths: /quotes: get: summary: Get all motivational quotes operationId: getAllQuotes responses: '200': description: A list of motivational quotes content: application/json: schema: type: array items: $ref: '#/components/schemas/Quote' /quotes/random: get: summary: Get a random motivational quote operationId: getRandomQuote responses: '200': description: A random motivational quote content: application/json: schema: $ref: '#/components/schemas/Quote' /quotes/{id}: get: summary: Get a motivational quote by ID operationId: getQuoteById parameters: - name: id in: path required: true schema: type: integer responses: '200': description: A motivational quote content: application/json: schema: $ref: '#/components/schemas/Quote' '404': description: Quote not found components: schemas: Quote: type: object required: - id - quote properties: id: type: integer quote: type: string


Trebao sam izvršiti samo jedno ručno ažuriranje — provjeriti jesu li svojstva id i quote potrebna za shemu Quote . I to samo zato što sam zaboravio spomenuti ovo ograničenje za ChatGPT u svom izvornom upitu.

Uz to, spremni smo razviti novu uslugu korištenjem API-First pristupa.

Izrada Spring Boot servisa korištenjem API-Firsta

Za ovaj primjer, koristit ću Spring Boot CLI za stvaranje novog projekta. Evo kako možete instalirati CLI koristeći Homebrew:


 $ brew tap spring-io/tap $ brew install spring-boot

Napravite novu Spring Boot Service

Projekt ćemo nazvati quotes , stvarajući ga sljedećom naredbom:


 $ spring init --dependencies=web quotes


Pogledajmo sadržaj mape s quotes :


 $ cd quotes && ls -la total 72 drwxr-xr-x@ 11 jvester 352 Mar 1 10:57 . drwxrwxrwx@ 90 jvester 2880 Mar 1 10:57 .. -rw-r--r--@ 1 jvester 54 Mar 1 10:57 .gitattributes -rw-r--r--@ 1 jvester 444 Mar 1 10:57 .gitignore -rw-r--r--@ 1 jvester 960 Mar 1 10:57 HELP.md -rw-r--r--@ 1 jvester 545 Mar 1 10:57 build.gradle drwxr-xr-x@ 3 jvester 96 Mar 1 10:57 gradle -rwxr-xr-x@ 1 jvester 8762 Mar 1 10:57 gradlew -rw-r--r--@ 1 jvester 2966 Mar 1 10:57 gradlew.bat -rw-r--r--@ 1 jvester 28 Mar 1 10:57 settings.gradle drwxr-xr-x@ 4 jvester 128 Mar 1 10:57 src


Zatim uređujemo datoteku build.gradle kao što je prikazano u nastavku kako bismo usvojili API-First pristup.


 plugins { id 'java' id 'org.springframework.boot' version '3.4.3' id 'io.spring.dependency-management' version '1.1.7' id 'org.openapi.generator' version '7.12.0' } openApiGenerate { generatorName = "spring" inputSpec = "$rootDir/src/main/resources/static/openapi.yaml" outputDir = "$buildDir/generated" apiPackage = "com.example.api" modelPackage = "com.example.model" configOptions = [ dateLibrary: "java8", interfaceOnly: "true", useSpringBoot3: "true", useBeanValidation: "true", skipDefaultInterface: "true" ] } group = 'com.example' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.openapitools:jackson-databind-nullable:0.2.6' implementation 'io.swagger.core.v3:swagger-annotations:2.2.20' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } sourceSets { main { java { srcDirs += "$buildDir/generated/src/main/java" } } } compileJava.dependsOn tasks.openApiGenerate tasks.named('test') { useJUnitPlatform() }


Konačno, postavljamo generiranu OpenAPI specifikaciju u mapu resources/static kao openapi.yaml .

Generirajte API i objekte modela

Nakon otvaranja projekta u IntelliJ-u, izvršio sam sljedeću naredbu za izgradnju API-jevih stubova i objekata modela.


 ./gradlew clean build


Sada možemo vidjeti api i objekte model stvorene iz naše OpenAPI specifikacije. Evo datoteke QuotesAPI.java :


Dodajte poslovnu logiku

S osnovnom uslugom koja je spremna i već se pridržava našeg OpenAPI ugovora, počinjemo dodavati neku poslovnu logiku usluzi.


Prvo stvaramo klasu QuotesRepository koja vraća podatke za našu uslugu. Kao što je gore navedeno, to bi normalno bilo pohranjeno u nekom namjenskom sloju postojanosti. Za ovaj primjer, tvrdo kodiranje podataka u vrijednosti od pet citata funkcionira sasvim dobro i drži nas usredotočenima.


 @Repository public class QuotesRepository { public static final List<Quote> QUOTES = List.of( new Quote() .id(1) .quote("The greatest glory in living lies not in never falling, but in rising every time we fall."), new Quote() .id(2) .quote("The way to get started is to quit talking and begin doing."), new Quote() .id(3) .quote("Your time is limited, so don't waste it living someone else's life."), new Quote() .id(4) .quote("If life were predictable it would cease to be life, and be without flavor."), new Quote() .id(5) .quote("If you set your goals ridiculously high and it's a failure, you will fail above everyone else's success.") ); public List<Quote> getAllQuotes() { return QUOTES; } public Optional<Quote> getQuoteById(Integer id) { return Optional.ofNullable(QUOTES.stream().filter(quote -> quote.getId().equals(id)).findFirst().orElse(null)); } }


Zatim stvaramo QuotesService koji će komunicirati s QuotesRepository . Ovim pristupom podaci će biti odvojeni od poslovne logike.


 @RequiredArgsConstructor @Service public class QuotesService { private final QuotesRepository quotesRepository; public List<Quote> getAllQuotes() { return quotesRepository.getAllQuotes(); } public Optional<Quote> getQuoteById(Integer id) { return quotesRepository.getQuoteById(id); } public Quote getRandomQuote() { List<Quote> quotes = quotesRepository.getAllQuotes(); return quotes.get(ThreadLocalRandom.current().nextInt(quotes.size())); } }


Konačno, samo trebamo implementirati QuotesApi generiran iz našeg API-First pristupa:


 @Controller @RequiredArgsConstructor public class QuotesController implements QuotesApi { private final QuotesService quotesService; @Override public ResponseEntity<List<Quote>> getAllQuotes() { return new ResponseEntity<>(quotesService.getAllQuotes(), HttpStatus.OK); } @Override public ResponseEntity<Quote> getQuoteById(Integer id) { return quotesService.getQuoteById(id) .map(quote -> new ResponseEntity<>(quote, HttpStatus.OK)) .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND)); } @Override public ResponseEntity<Quote> getRandomQuote() { return new ResponseEntity<>(quotesService.getRandomQuote(), HttpStatus.OK); } }


U ovom trenutku imamo potpuno funkcionalan API za motivacijske citate, zajedno s malom zbirkom odgovora.

Neke završne stavke

Spring Boot nam daje opciju za web-bazirano korisničko sučelje Swagger Docs putem ovisnosti springdoc-openapi-starter-webmvc-ui .


 dependencies { ... implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.5' ... }


Dok okvir omogućuje inženjerima korištenje jednostavnih komentara za opisivanje svog API-ja, možemo koristiti našu postojeću datoteku openapi.yaml u mapi resources/static .


Ovaj pristup možemo implementirati u datoteci application-properties.yaml , zajedno s nekoliko drugih manjih ažuriranja konfiguracije:


 server: port: ${PORT:8080} spring: application: name: quotes springdoc: swagger-ui: path: /swagger-docs url: openapi.yaml


Samo zabave radi, dodajmo datoteku banner.txt za korištenje kada se usluga pokrene. Ovu datoteku stavljamo u mapu resources .


 ${AnsiColor.BLUE} _ __ _ _ _ ___ | |_ ___ ___ / _` | | | |/ _ \| __/ _ \/ __| | (_| | |_| | (_) | || __/\__ \ \__, |\__,_|\___/ \__\___||___/ |_| ${AnsiColor.DEFAULT} :: Running Spring Boot ${AnsiColor.BLUE}${spring-boot.version}${AnsiColor.DEFAULT} :: Port #${AnsiColor.BLUE}${server.port}${AnsiColor.DEFAULT} ::


Sada, kada pokrenemo uslugu lokalno, možemo vidjeti natpis:


Nakon pokretanja, možemo provjeriti rade li Swagger dokumenti posjetom krajnje točke /swagger-docs .



Konačno, izradit ćemo novo spremište temeljeno na Gitu kako bismo mogli pratiti sve buduće promjene:


 $ git init $ git add . $ git commit -m "Initial commit for the Motivational Quotes API"


Sada, da vidimo koliko brzo možemo implementirati našu uslugu .

Korištenje Herokua za završetak putovanja

Do sada je primarni fokus predstavljanja moje nove ideje bio stvaranje OpenAPI specifikacije i pisanje neke poslovne logike za moju uslugu. Spring Boot je sredio sve ostalo umjesto mene.


Kada je riječ o pokretanju moje usluge, radije koristim Heroku jer odlično pristaje za Spring Boot usluge. Mogu brzo implementirati svoje usluge, a da se ne zaglavim problemima u infrastrukturi oblaka. Heroku također olakšava prosljeđivanje konfiguracijskih vrijednosti za moje aplikacije temeljene na Javi .


Kako bismo odgovarali verziji Jave koju koristimo, stvaramo datoteku system.properties u korijenskoj mapi projekta. Datoteka ima jedan redak:


 java.runtime.version = 17


Zatim stvaram Procfile na istoj lokaciji za prilagodbu ponašanja implementacije. Ova datoteka također ima jedan redak:


 web: java -jar build/libs/quotes-0.0.1-SNAPSHOT.jar


Vrijeme je za raspoređivanje. Uz Heroku CLI , mogu implementirati uslugu pomoću nekoliko jednostavnih naredbi. Prvo provjeravam autentičnost CLI-ja, a zatim stvaram novu Heroku aplikaciju.


 $ heroku login $ heroku create Creating app... done, vast-crag-43256 https://vast-crag-43256-bb5e35ea87de.herokuapp.com/ | https://git.heroku.com/vast-crag-43256.git


Moja instanca aplikacije Heroku zove se vast-crag-43256 (mogao sam unijeti određeno ime), a usluga će se izvoditi na https://vast-crag-43256-bb5e35ea87de.herokuapp.com/.


Zadnje što treba učiniti je implementirati uslugu korištenjem Git naredbe za prosljeđivanje koda Herokuu:


 $ git push heroku master


Kada se ova naredba završi, možemo potvrditi uspješnu implementaciju putem Heroku nadzorne ploče:


Sada smo spremni za probnu vožnju naše nove usluge!

Motivacijski citati na djelu

S uslugom Motivational Quotes koja radi na Herokuu, možemo potvrditi da sve radi prema očekivanjima pomoću niza curl naredbi.


Prvo, idemo dobiti potpuni popis svih pet motivacijskih citata:


 $ curl \ --location 'https://vast-crag-43256-bb5e35ea87de.herokuapp.com/quotes'


 [ { "id":1, "quote":"The greatest glory in living lies not in never falling, but in rising every time we fall." }, { "id":2, "quote":"The way to get started is to quit talking and begin doing." }, { "id":3, "quote":"Your time is limited, so don't waste it living someone else's life." }, { "id":4, "quote":"If life were predictable it would cease to be life, and be without flavor." }, { "id":5, "quote":"If you set your goals ridiculously high and it's a failure, you will fail above everyone else's success." } ]


Dohvatimo jedan motivacijski citat prema ID-u:


 $ curl \ --location 'https://vast-crag-43256-bb5e35ea87de.herokuapp.com/quotes/3'


 { "id":3, "quote":"Your time is limited, so don't waste it living someone else's life." }


Uzmimo slučajni motivacijski citat:


 $ curl --location \ 'https://vast-crag-43256-bb5e35ea87de.herokuapp.com/quotes/random'


 { "id":5, "quote":"If you set your goals ridiculously high and it's a failure, you will fail above everyone else's success." }


Možemo čak pregledavati i Swagger dokumente.


Zaključak

Vrijeme izlaska na tržište može učiniti ili uništiti svaku ideju. To je razlog zašto su startupi laserski usredotočeni na isporuku svojih inovacija što je brže moguće. Što je duže potrebno da stignete do cilja, to je veći rizik da natjecatelj stigne prije vas.


Moji se čitatelji mogu sjetiti moje osobne izjave o misiji, za koju smatram da se može primijeniti na bilo kojeg IT stručnjaka:


"Usmjerite svoje vrijeme na pružanje značajki/funkcionalnosti koje povećavaju vrijednost vašeg intelektualnog vlasništva. Iskoristite okvire, proizvode i usluge za sve ostalo."

— J. Vester


U ovom smo članku vidjeli kako je Spring Boot riješio sve što je potrebno za implementaciju RESTful API-ja. Koristeći ChatGPT, uspjeli smo čak ljudskim riječima izraziti što želimo da naša usluga bude, a to nam je za nekoliko sekundi stvorilo OpenAPI specifikaciju. To nam je omogućilo da iskoristimo API-First pristup. Kad smo bili spremni, mogli smo isporučiti našu ideju koristeći Heroku izdavanjem nekoliko CLI naredbi.

Spring Boot, ChatGPT i Heroku pružili su okvire i usluge kako bih mogao ostati fokusiran na realizaciju svoje ideje. Kao rezultat toga, mogao sam se pridržavati svoje osobne izjave o misiji i, što je još važnije, brzo isporučiti svoju ideju. Sve što sam trebao učiniti bilo je usredotočiti se na poslovnu logiku koja stoji iza moje ideje—i tako treba biti!


Ako ste zainteresirani, izvorni kod za ovaj članak možete pronaći na GitLabu .


Ugodan dan!

L O A D I N G
. . . comments & more!

About Author

John Vester HackerNoon profile picture
John Vester@johnjvester
Information Technology professional with 25+ years expertise in application design and architecture.

VIJESI OZNAKE

OVAJ ČLANAK JE PREDSTAVLJEN U...

Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks