Een API bouwen met het Spark Java Framework

1. Inleiding

In dit artikel zullen we een korte inleiding hebben tot het Spark-framework. Spark-framework is een webframework voor snelle ontwikkeling dat is geïnspireerd op het Sinatra-framework voor Ruby en is gebouwd rond de Java 8 Lambda Expression-filosofie, waardoor het minder uitgebreid is dan de meeste applicaties die in andere Java-frameworks zijn geschreven.

Het is een goede keuze als u een Node.js zoals ervaring bij het ontwikkelen van een web-API of microservices in Java. Met Spark kun je een REST API gereed hebben om JSON te leveren in minder dan tien regels code.

We zullen snel beginnen met een "Hello World" -voorbeeld, gevolgd door een eenvoudige REST API.

2. Maven afhankelijkheden

2.1. Spark Framework

Neem de volgende Maven-afhankelijkheid op in uw pom.xml:

 com.sparkjava spark-core 2.5.4 

Je kunt de nieuwste versie van Spark vinden op Maven Central.

2.2. Gson-bibliotheek

Op verschillende plaatsen in het voorbeeld zullen we de Gson-bibliotheek gebruiken voor JSON-bewerkingen. Om Gson in uw project op te nemen, neemt u deze afhankelijkheid op in uw pom.xml:

 com.google.code.gson gson 2.8.0 

Je kunt de nieuwste versie van Gson vinden op Maven Central.

3. Aan de slag met Spark Framework

Laten we eens kijken naar de basisbouwstenen van een Spark-applicatie en een snelle webservice demonstreren.

3.1. Routes

Webservices in Spark Java zijn gebaseerd op routes en hun handlers. Routes zijn essentiële elementen in Spark. Volgens de documentatie bestaat elke route uit drie eenvoudige stukken: een werkwoord, een pad, en een Bel terug.

  1. De werkwoord is een methode die overeenkomt met een HTTP-methode. Werkwoordsmethoden zijn onder meer: krijgen, plaatsen, plaatsen, verwijderen, hoofd, traceren, verbinden, en opties
  2. De pad (ook wel een routepatroon genoemd) bepaalt naar welke URI ('s) de route moet luisteren en waarop moet worden gereageerd
  3. De Bel terug is een handlerfunctie die wordt aangeroepen voor een bepaald werkwoord en pad om een ​​antwoord te genereren en terug te sturen op het corresponderende HTTP-verzoek. Een callback heeft een request-object en een response-object als argumenten

Hier laten we de basisstructuur zien voor een route die de krijgen werkwoord:

get ("/ uw-route-pad /", (verzoek, antwoord) -> {// uw terugbelcode});

3.2. Hallo wereld API

Laten we een eenvoudige webservice maken die twee routes heeft voor GET-verzoeken en als antwoord "Hallo" -berichten retourneert. Deze routes gebruiken de krijgen methode, wat een statische import uit de klasse is vonk. vonk:

importeer statische spark.Spark. *; openbare klasse HelloWorldService {openbare statische leegte hoofd (String [] args) {get ("/ hallo", (req, res) -> "Hallo wereld"); get ("/ hallo /: naam", (req, res) -> {return "Hallo," + req.params (": naam");}); }}

Het eerste argument voor de krijgen methode is het pad voor de route. De eerste route bevat een statisch pad dat slechts één URI vertegenwoordigt ("/Hallo").

Het pad van de tweede route ("/ Hallo /: naam") bevat een tijdelijke aanduiding voor de "naam" parameter, zoals aangegeven door de parameter vooraf te laten gaan met een dubbele punt (":"). Deze route wordt aangeroepen als reactie op GET-verzoeken aan URI's zoals "/ Hallo / Joe" en "/Hoi Mary".

Het tweede argument voor de krijgen method is een lambda-uitdrukking die een functioneel programmeeraroma aan dit raamwerk geeft.

De lambda-expressie heeft verzoek en antwoord als argumenten en helpt het antwoord te retourneren. We zullen onze controllerlogica in de lambda-expressie voor de REST API-routes plaatsen, zoals we later in deze tutorial zullen zien.

3.3. Het testen van de Hello World API

Na het runnen van de klas HalloWorldService als een normale Java-klasse hebt u toegang tot de service op de standaardpoort van 4567 met behulp van de routes die zijn gedefinieerd met de krijgen methode hierboven.

Laten we eens kijken naar het verzoek en de reactie voor de eerste route:

Verzoek:

GET // localhost: 4567 / hallo

Reactie:

Hallo Wereld

Laten we de tweede route testen, langs de naam parameter in zijn pad:

Verzoek:

GET // localhost: 4567 / hallo / baeldung

Reactie:

Hallo, baeldung

Kijk hoe de plaatsing van de tekst "Baeldung" in de URI werd gebruikt om het routepatroon af te stemmen "/ Hallo /: naam" - ervoor zorgen dat de callback-handlerfunctie van de tweede route wordt aangeroepen.

4. Het ontwerpen van een RESTvolle dienst

In deze sectie zullen we een eenvoudige REST-webservice ontwerpen voor het volgende Gebruiker entiteit:

openbare klasse Gebruiker {privé String-id; private String voornaam; private String achternaam; privé String-e-mail; // constructeurs, getters en setters}

4.1. Routes

Laten we een lijst maken van de routes waaruit onze API bestaat:

  • GET / gebruikers - krijg een lijst van alle gebruikers
  • GET / users /: id - verkrijg gebruiker met opgegeven id
  • POST / gebruikers /: id - voeg een gebruiker toe
  • PUT / gebruikers /: id - bewerk een bepaalde gebruiker
  • OPTIONS / gebruikers /: id - controleer of een gebruiker bestaat met de opgegeven id
  • DELETE / gebruikers /: id - verwijder een bepaalde gebruiker

4.2. De gebruikersservice

Hieronder is de Gebruikersservice interface die de CRUD-bewerkingen voor het Gebruiker entiteit:

openbare interface UserService {public void addUser (User user); openbare verzameling getUsers (); openbare gebruiker getUser (String-id); openbare gebruiker editUser (gebruiker gebruiker) gooit UserException; openbare ongeldige deleteUser (String-id); openbare booleaanse userExist (String-id); }

Voor demonstratiedoeleinden bieden we een Kaart implementatie hiervan Gebruikersservice interface in de GitHub-code om persistentie te simuleren. U kunt uw eigen implementatie aanleveren met de database en persistentielaag van uw keuze.

4.3. De JSON-antwoordstructuur

Hieronder ziet u de JSON-structuur van de antwoorden die in onze REST-service worden gebruikt:

{status: bericht: gegevens:}

De toestand veldwaarde kan een van beide zijn SUCCES of FOUT. De gegevens veld bevat de JSON-weergave van de geretourneerde gegevens, zoals een Gebruiker of verzameling van Gebruikers.

Als er geen gegevens worden geretourneerd, of als het toestand is FOUT, vullen we de bericht veld om een ​​reden voor de fout of het ontbreken van retourgegevens aan te geven.

Laten we de bovenstaande JSON-structuur weergeven met behulp van een Java-klasse:

openbare klasse StandardResponse {privé StatusResponse-status; privé String-bericht; privé JsonElement-gegevens; public StandardResponse (StatusResponse-status) {// ...} public StandardResponse (StatusResponse-status, String-bericht) {// ...} public StandardResponse (StatusResponse-status, JsonElement-gegevens) {// ...} // getters en setters }

waar StatusResponse is een opsomming gedefinieerd zoals hieronder:

openbare opsomming StatusResponse {SUCCESS ("Succes"), ERROR ("Fout"); privé String-status; // constructeurs, getters}

5. Implementeren van RESTful Services

Laten we nu de routes en handlers voor onze REST API implementeren.

5.1. Controllers maken

De volgende Java-klasse bevat de routes voor onze API, inclusief de werkwoorden en paden en een overzicht van de handlers voor elke route:

public class SparkRestExample {public static void main (String [] args) {post ("/ users", (request, response) -> {// ...}); get ("/ gebruikers", (verzoek, antwoord) -> {// ...}); get ("/ gebruikers /: id", (verzoek, antwoord) -> {// ...}); put ("/ gebruikers /: id", (verzoek, antwoord) -> {// ...}); delete ("/ gebruikers /: id", (verzoek, antwoord) -> {// ...}); options ("/ gebruikers /: id", (verzoek, antwoord) -> {// ...}); }}

We zullen de volledige implementatie van elke routehandler in de volgende subsecties laten zien.

5.2. Voeg gebruiker toe

Hieronder is de post method response handler die een Gebruiker:

post ("/ users", (request, response) -> {response.type ("application / json"); User user = nieuwe Gson (). fromJson (request.body (), User.class); userService.addUser (gebruiker); retourneer nieuwe Gson () .toJson (nieuwe StandardResponse (StatusResponse.SUCCESS));});

Opmerking: In dit voorbeeld is de JSON-weergave van het Gebruiker object wordt doorgegeven als de onbewerkte tekst van een POST-verzoek.

Laten we de route testen:

Verzoek:

POST // localhost: 4567 / gebruikers {"id": "1012", "email": "[email protected]", "firstName": "Mac", "lastName": "Mason1"}

Reactie:

{"status": "SUCCESS"}

5.3. Haal alle gebruikers op

Hieronder is de krijgen method response handler die alle gebruikers van de Gebruikersservice:

get ("/ users", (request, response) -> {response.type ("application / json"); retourneer nieuwe Gson (). toJson (nieuwe StandardResponse (StatusResponse.SUCCESS, nieuwe Gson () .toJsonTree (userService. getUsers ())));});

Laten we nu de route testen:

Verzoek:

GET // localhost: 4567 / gebruikers

Reactie:

{"status": "SUCCESS", "data": [{"id": "1014", "firstName": "John", "lastName": "Miller", "email": "[email protected]"} , {"id": "1012", "firstName": "Mac", "lastName": "Mason1", "email": "[email protected]"}]}

5.4. Gebruiker ophalen op ID

Hieronder is de krijgen method response handler die een Gebruiker met het gegeven ID kaart:

get ("/ users /: id", (request, response) -> {response.type ("application / json"); retourneer nieuwe Gson (). toJson (nieuwe StandardResponse (StatusResponse.SUCCESS, nieuwe Gson () .toJsonTree (userService.getUser (request.params (": id")))));});

Laten we nu de route testen:

Verzoek:

GET // localhost: 4567 / gebruikers / 1012

Reactie:

{"status": "SUCCESS", "data": {"id": "1012", "firstName": "Mac", "lastName": "Mason1", "email": "[email protected]"}}

5.5. Bewerk een gebruiker

Hieronder is de leggen method response handler, die de gebruiker bewerkt die de ID kaart geleverd in het routepatroon:

put ("/ users /: id", (request, response) -> {response.type ("application / json"); User toEdit = nieuwe Gson (). fromJson (request.body (), User.class); Gebruiker editUser = userService.editUser (toEdit); if (editUser! = Null) {retourneer nieuwe Gson (). ToJson (nieuwe StandardResponse (StatusResponse.SUCCESS, nieuwe Gson () .toJsonTree (editUser)));} else {retourneer nieuw Gson (). ToJson (nieuwe StandardResponse (StatusResponse.ERROR, nieuwe Gson () .toJson ("Gebruiker niet gevonden of fout bij bewerken")));}});

Opmerking: In dit voorbeeld worden de gegevens in de onbewerkte tekst van een POST-verzoek doorgegeven als een JSON-object waarvan de eigenschapsnamen overeenkomen met de velden van de Gebruiker object dat moet worden bewerkt.

Laten we de route testen:

Verzoek:

PUT // localhost: 4567 / gebruikers / 1012 {"lastName": "Mason"}

Reactie:

{"status": "SUCCESS", "data": {"id": "1012", "firstName": "Mac", "lastName": "Mason", "email": "[email protected]"}}

5.6. Verwijder een gebruiker

Hieronder is de verwijderen method response handler, die de Gebruiker met het gegeven ID kaart:

delete ("/ users /: id", (request, response) -> {response.type ("application / json"); userService.deleteUser (request.params (": id")); retourneer nieuwe Gson (). toJson (nieuwe StandardResponse (StatusResponse.SUCCESS, "gebruiker verwijderd"));});

Laten we nu de route testen:

Verzoek:

VERWIJDEREN // localhost: 4567 / gebruikers / 1012

Reactie:

{"status": "SUCCESS", "message": "gebruiker verwijderd"}

5.7. Controleer of de gebruiker bestaat

De opties methode is een goede keuze voor voorwaardelijke controle. Hieronder is de opties method response handler die zal controleren of een Gebruiker met het gegeven ID kaart bestaat:

options ("/ users /: id", (request, response) -> {response.type ("application / json"); return new Gson (). toJson (new StandardResponse (StatusResponse.SUCCESS, (userService.userExist (request .params (": id")))? "Gebruiker bestaat": "Gebruiker bestaat niet"));});

Laten we nu de route testen:

Verzoek:

OPTIES // localhost: 4567 / gebruikers / 1012

Reactie:

{"status": "SUCCESS", "message": "Gebruiker bestaat"}

6. Conclusie

In dit artikel hebben we een korte inleiding gehad tot het Spark-framework voor snelle webontwikkeling.

Dit framework wordt voornamelijk gepromoot voor het genereren van microservices in Java. Node.js ontwikkelaars met Java-kennis die gebruik willen maken van bibliotheken die op JVM-bibliotheken zijn gebouwd, moeten zich thuis voelen bij het gebruik van dit framework.

En zoals altijd kun je alle bronnen voor deze tutorial vinden in het Github-project.