miércoles, 7 de marzo de 2018

Desarrollo RESTful WebService APIs with JAX-RS Parte 1


github https://github.com/jalbertomr/RESTfulWebServiceJAX-RSMaven.git

Messenger: Social Media application API

REST y HTML
 - Resource based URIs
 - HTTP methods
 - HTTP statuc code
 - Message headers

Roy Fielding, one of the authors of the HTTP specification
HTTP Hyper Text Transfer Protocol
HTML Hyper Text Markup Language
Resources locations

client     <------>   Web Service

Weather WebService
{
   weather:__
   temperature:__
   wind speed:__
}

Addresses
Weather website:
weatherapp.com/weatherLookup.do?zipcode=12345
Resource based URI
weatherapp.com/zipcode/12345
weatherapp.com/zipcode/43234
wweatherapp.com/countries/brazil

HTTP METHODS

GET
POST
        PUT
DELETE

        Client --------------- weatherapp.com/zipcode/12345

METADATA
    HTTP Status codes
200 - Success
500 - Server Error
404 - Not found
                ... - ...
Message Header
Content types
text/html
application/json

Diagrama UML

USER -------------------E  Message
  |                _________|_______       
  |                |        |       |
  |                M        M       M
  -----------E Comment    Like     Share

Web application URIs
   Get a message with ID 10 with Struts you get something like this
/getMessages.do?id=10
or /retieveMessage.action?id=10          nomenclatura basada en accion

Static Websites
site
          content
     index.html
     site-map.html
Static Profile pages
        beto  --> beto.html
  juan.html
  lucas.html
  vene.html

profiles

Resource Based URIs  usar nombres no verbos, son recursos
/profiles/Beto
/profiles/juan
/profiles/{profileName}        de forma generica

/messages        todos los mensajes
/messages/1 mensaje con id = 1
/messages/2 mensaje con id = 2
/messages/{messageId}   generico

Resources Relations

        Message ------E Comment       uno a muchos

Comments
/comments/{commentId}

messages
   1
              comments
                 1.html
2.html   ---> /messages/1/comments/2
3.html        /messages/{messageId}/comments/{commentId}
      1.html
   2
              comments
                 4.html
                 5.html
              2.html

Segundo Nivel

  Likes
/messages/{messageId}/likes/{likeId}
  Shares
        /messages/{messageId}/shares/{shareId}
  Comments
        /messages/{messageId}/comments/{commentId}

Primer Nivel

Profiles
/profiles/{profileName}
Messages
/messages/{messageId}

        instance resources URIs
collection resources URIs
Collections

How about all comments?    /messages/{messageId}/comments   -->  no funcionara si no damos el messageId
   /comments --> funcionara
Filtering Results
Query Params, Pagination ans size

  /messages?offset=30&limit=10
    starting point   size

Custom Filters

/messages?year=2014
/messages?year=2014&offset=30&limit=10

HTTP Methods
    URIs
/getMessages.do?id=10      nomenclatura basada en accion
/messages/10    nomenclatura basada en recurso

metodos comunes  GET, POST, PUT, DELETE
not tan comunes  HEAD, OPTIONS

/getProducts.do?id=10      --> GET /products/10
/deleteOrder.do?id=10    -->  DELETE /orders/10

Messenger
getting a message
GET /messages/{messageId}

updating a message
PUT /message/{messageId}  el body debe contener los datos a agregar

adding a message
POST /message          el body debe contener los datos a agregar

deleteing a message
DELETE /messages/{messageId}

Collection URI
GET    /messages obtiene todos los mensajes
DELETE /messages/10/comments borra todos los comentarios del mensaje 10
GET    /messages/10/comments trae todos los comentarios del mensaje 10
POST   /messages/10/comments crea nuevo comentario para el mensaje 10
PUT    /messages/10/comments reemplaza todos los comentarios del mensaje 10 con una nueva lista de comentarios.

IDEMPOTENTE se pueden repetir GET PUT DELETE
No se puede repetir POST

Funcionalidades:
  - Post Message
  - Comment on messages
  - Likes and share messages
  - User Profiles



Se crea proyecto nuevo maven en IntelliJ se le agrega dependecia

<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.archetypes/jersey-quickstart-webapp -->
<dependency>
    <groupId>org.glassfish.jersey.archetypes</groupId>
    <artifactId>jersey-quickstart-webapp</artifactId>
    <version>2.26</version>
</dependency>

se crea artifact con el proyecto war y me da la pagina de inicio de jersey

con servidor web payara

en webapp/WEB-INF/web.xml
se usa un servlet que viene de org.glassfish.jersey.servlet.ServletContainer
que se mapea a http://localhost:8080/messenger/webapi/myresource

myresource esta en main/java/org.data.bext/MyResource.java con anotacion @path("myresource") clase MyResource metodo getIt()

en web.xml
    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>org.data.bext</param-value>           donde jersey va a buscar las clases con las anotaciones para la API @GET,@POST...
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>


-se crea public @Path("/messages")
public class MessageResource {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getMessages() {
        return "MessageResource-getMessages()=mi recurso";
    }
}

y se llama con http://localhost:8080/messenger/webapi/messages

Paso 5 se agrega a Message la anotacion @XmlRootElement

Se van a agregar a MessageService las operaciones
MessageService()
getAllMessages():List<Message>
getMessage(long):Message
addMessage(Message):Message
updateMessage(Message):Message
removeMessage(long):Message

- Se adapta MessageResource para obtener parametros con @PathParam
  @GET
    @Path("/{messageId}")
    @Produces(MediaType.APPLICATION_XML)
    public Message getMessage(@PathParam("messageId") long Id) {
        return messageService.getMessage(Id);
    }

   pueden sacarse más parametros /something/{id1}/name/{id2}
@PathParam("id1") int id1,
@PathParam("id2") int id2


   /profiles/{profileId}
   /profiles

- Implementing profileResource
- Subresources
    en MessageResources.java
    @Path("/{messageId}/comentarios")
    public CommentResource getAllComments() {
        return new CommentResource();

   en CommentsResources.java
   @GET
    @Path("/{commentId}")
    public String getComment(@PathParam("messageId") long messageID,@PathParam("commentId") long commentID) {
        return "comentario a regresar(commentID): " + commentID + "del mensage:" + messageID;
    }


















En MessageResource.java

@GETpublic List<Message> getMessages(@QueryParam("year") int year,
                                 @QueryParam("start") int start,
                                 @QueryParam("size") int size) {
    if (year > 0 ) return messageService.getAllMessageForYear(year);
    if (start >= 0 && size > 0) {
        return messageService.getAllMessagePaginated(start, size);
    }
    return messageService.getAllMessages();
}




...

No hay comentarios:

Publicar un comentario