web-dev-qa-db-fra.com

Étapes à suivre pour générer REST Documentation API

J'essaie de générer une documentation sur l'API REST basée sur Swagger pour certaines de mes API REST existantes.

Quelles sont les étapes nécessaires ou préalables pour cela? Je travaille sur Windows OS.

9
user4596341

swagger-core est notre propre bibliothèque d'intégration avec les projets JAX-RS

Nous fournissons un tutoriel simple pour expliquer comment l’intégrer à votre code. C'est assez simple. Les annotations sont également documentés pour vous aider à comprendre ce qui doit être ajouté et où.

Une fois les étapes ci-dessus terminées, vous obtenez une sortie d'un fichier swagger.json et swagger.yaml. À ce stade, vous souhaiterez intégrer swagger-ui à votre application. Il y a différentes façons de le faire. Une solution consiste à l'intégrer à votre processus de construction, comme indiqué dans nos exemples.

La combinaison des deux plugins le fera pour vous:

  <plugin>
    <groupId>com.googlecode.maven-download-plugin</groupId>
    <artifactId>download-maven-plugin</artifactId>
    <version>1.2.1</version>
    <executions>
      <execution>
        <id>swagger-ui</id>
        <goals>
          <goal>wget</goal>
        </goals>
        <configuration>
          <url>https://github.com/swagger-api/swagger-ui/archive/master.tar.gz</url>
          <unpack>true</unpack>
          <outputDirectory>${project.build.directory}</outputDirectory>
        </configuration>
      </execution>
    </executions>
  </plugin>
  <plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <version>2.6</version>
    <executions>
      <execution>
        <id>copy-resources</id>
        <phase>validate</phase>
        <goals>
          <goal>copy-resources</goal>
        </goals>
        <configuration>
          <outputDirectory>target/${project.artifactId}-${project.version}</outputDirectory>
          <resources>
            <resource>
              <directory>${project.build.directory}/swagger-ui-master/dist</directory>
              <filtering>true</filtering>
              <excludes>
                <exclude>index.html</exclude>
              </excludes>
            </resource>
          </resources>
        </configuration>
      </execution>
    </executions>
  </plugin>

Vous devez simplement vous assurer d’exécuter également l’objectif package, donc quelque chose comme mvn package install si vous voulez l’installer (mais cela dépend de votre processus de développement).

8
Ron

Swagger fournit quelques options sur la manière de concevoir la documentation de votre API.

Vous devez d'abord comprendre qu'il est divisé en deux parties:

CORE est utilisé pour générer un JSON avec des informations pertinentes sur votre API . Ce JSON suit le modèle swagger.

INTERFACE lira alors ce JSON et générera du HTML

Tout d'abord, vous annoterez vos contrôleurs et vos points de terminaison. Vous aurez besoin de «swagger-core» et de «swagger-annotations» pour cela.

Ensuite, vous avez deux options:

a) Fournissez un point de terminaison pour générer et servir JSON et utilisez swagger-ui pour le lire afin de générer du code HTML

b) Utilisez le plugin maven swagger-maven pour générer le JSON et le code HTML lors de la compilation.

Plus d'infos sur:

http://swagger.io/

https://github.com/swagger-api/swagger-spec#additional-libraries

Si vous utilisez Spring, je vous suggère de consulter https://github.com/springfox

Si vous préférez le plugin Maven, voir https://github.com/kongchen

3
tbraun

Vous pouvez utiliser les étapes suivantes:

POM

<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>org.viquar./groupId>
    <artifactId>messenger</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>messenger</name>

    <build>
        <finalName>messenger</finalName>
        <plugins>
            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <inherited>true</inherited>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.glassfish.jersey</groupId>
                <artifactId>jersey-bom</artifactId>
                <version>${jersey.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>


        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!-- Swagger documentations -->
        <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-jersey2-jaxrs_2.10</artifactId>
            <version>1.3.12</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-jersey2-jaxrs</artifactId>
            <version>1.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>${jersey.version}</version>
        </dependency>
    </dependencies>
    <properties>
        <jersey.version>2.16</jersey.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

Télécharger:

Vous pouvez utiliser le code swagger-ui tel quel! Pas besoin de construire ou de recompiler - il suffit de cloner ce dépôt et d'utiliser les fichiers pré-construits dans le dossier dist. Si vous aimez swagger-ui en l'état, arrêtez-vous ici.

http://swagger.io/swagger-ui/

Les étapes suivantes vous donnent un exemple de bout en bout

DatabaseClass.Java

package org.viquar.database;

import Java.util.HashMap;
import Java.util.Map;
import org.viquar.model.Message;
import org.viquar.model.Profile;

public class DatabaseClass {

    private static Map<Long, Message> messages = new HashMap<>();
    private static Map<String, Profile> profiles = new HashMap<>();


    public static Map<Long, Message> getMessages() {
        return messages;
    }

    public static Map<String, Profile> getProfiles() {
        return profiles;
    }
}

DataNotFoundException.Java

package org.viquar.exception;

public class DataNotFoundException extends RuntimeException {

    /**
     * 
     */
    private static final long serialVersionUID = -6328286661536343936L;


    public DataNotFoundException(String message) {
        super(message);
    }

}

DataNotFoundExceptionMapper.Java

package org.viquar.exception;

import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import org.viquar.model.ErrorMessage;

@Provider
public class DataNotFoundExceptionMapper implements ExceptionMapper<DataNotFoundException> {

    @Override
    public Response toResponse(DataNotFoundException ex) {
        ErrorMessage errorMessage = new ErrorMessage(ex.getMessage(), 404, "http://localhost:8080/JerseyRestPoc.Viquar.poc");
        return Response.status(Status.NOT_FOUND)
                .entity(errorMessage)
                .build();
    }

}

GenericExceptionMapper.Java

package org.viquar.exception;

import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import org.viquar.model.ErrorMessage;

// This class intentionally doesn't have the @Provider annotation.
// It has been disabled in order to try out other ways of throwing exceptions in JAX-RS

// @Provider
public class GenericExceptionMapper implements ExceptionMapper<Throwable> {

    @Override
    public Response toResponse(Throwable ex) {
        ErrorMessage errorMessage = new ErrorMessage(ex.getMessage(), 500, "http://localhost:8080/JerseyRestPoc.Viquar.poc");
        return Response.status(Status.INTERNAL_SERVER_ERROR)
                .entity(errorMessage)
                .build();
    }

}

Commentaire.Java

package org.viquar.model;

import Java.util.Date;

public class Comment {


    private long id;
    private String message;
    private Date created;
    private String author;

    public Comment() {

    }

    public Comment(long id, String message, String author) {
        this.id = id;
        this.message = message;
        this.author = author;
        this.created = new Date();
    }

    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public Date getCreated() {
        return created;
    }
    public void setCreated(Date created) {
        this.created = created;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }



}

ErrorMessage.Java

package org.viquar.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class ErrorMessage {

    private String errorMessage;
    private int errorCode;
    private String documentation;

    public ErrorMessage() {

    }

    public ErrorMessage(String errorMessage, int errorCode, String documentation) {
        super();
        this.errorMessage = errorMessage;
        this.errorCode = errorCode;
        this.documentation = documentation;
    }
    public String getErrorMessage() {
        return errorMessage;
    }
    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }
    public int getErrorCode() {
        return errorCode;
    }
    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }
    public String getDocumentation() {
        return documentation;
    }
    public void setDocumentation(String documentation) {
        this.documentation = documentation;
    }


}

Link.Java

package org.viquar.model;

public class Link {
    private String link;
    private String rel;

    public String getLink() {
        return link;
    }
    public void setLink(String link) {
        this.link = link;
    }
    public String getRel() {
        return rel;
    }
    public void setRel(String rel) {
        this.rel = rel;
    }


}

Message.Java

package org.viquar.model;

import Java.util.ArrayList;
import Java.util.Date;
import Java.util.HashMap;
import Java.util.List;
import Java.util.Map;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement
public class Message {

    private long id;
    private String message;
    private Date created;
    private String author;
    private Map<Long, Comment> comments = new HashMap<>();
    private List<Link> links = new ArrayList<>();

    public Message() {

    }

    public Message(long id, String message, String author) {
        this.id = id;
        this.message = message;
        this.author = author;
        this.created = new Date();
    }

    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public Date getCreated() {
        return created;
    }
    public void setCreated(Date created) {
        this.created = created;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    @XmlTransient
    public Map<Long, Comment> getComments() {
        return comments;
    }

    public void setComments(Map<Long, Comment> comments) {
        this.comments = comments;
    }

    public List<Link> getLinks() {
        return links;
    }

    public void setLinks(List<Link> links) {
        this.links = links;
    }

    public void addLink(String url, String rel) {
        Link link = new Link();
        link.setLink(url);
        link.setRel(rel);
        links.add(link);
    }


}

Profile.Java

package org.viquar.model;

import Java.util.Date;

import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Profile {

    private long id;
    private String profileName;
    private String firstName;
    private String lastName;
    private Date created;

    public Profile() {

    }

    public Profile(long id, String profileName, String firstName, String lastName) {
        this.id = id;
        this.profileName = profileName;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getProfileName() {
        return profileName;
    }
    public void setProfileName(String profileName) {
        this.profileName = profileName;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public Date getCreated() {
        return created;
    }
    public void setCreated(Date created) {
        this.created = created;
    }


}

ProfileResource.Java

package org.viquar.resources;

import Java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.viquar.model.Profile;
import org.viquar.service.ProfileService;

@Path("/profiles")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class ProfileResource {

    private ProfileService profileService = new ProfileService();



    @GET
    public List<Profile> getProfiles() {
        return profileService.getAllProfiles();
    }

    @POST
    public Profile addProfile(Profile profile) {
        return profileService.addProfile(profile);
    }

    @GET
    @Path("/{profileName}")
    public Profile getProfile(@PathParam("profileName") String profileName) {
        return profileService.getProfile(profileName);
    }

    @PUT
    @Path("/{profileName}")
    public Profile updateProfile(@PathParam("profileName") String profileName, Profile profile) {
        profile.setProfileName(profileName);
        return profileService.updateProfile(profile);
    }

    @DELETE
    @Path("/{profileName}")
    public void deleteProfile(@PathParam("profileName") String profileName) {
        profileService.removeProfile(profileName);
    }



}

MessageResource.Java

package org.viquar.resources;

import Java.net.URI;
import Java.util.List;
import javax.ws.rs.BeanParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.viquar.model.Message;
import org.viquar.resources.beans.MessageFilterBean;
import org.viquar.service.MessageService;
//
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;


@Path("/messages")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Api(value = "/messages", description = "Operation about orders")
public class MessageResource {

    MessageService messageService = new MessageService();

    @GET
    public List<Message> getMessages(@BeanParam MessageFilterBean filterBean) {

        if (filterBean.getYear() > 0) {
            return messageService.getAllMessagesForYear(filterBean.getYear());
        }
        if (filterBean.getStart() >= 0 && filterBean.getSize() > 0) {
            return messageService.getAllMessagesPaginated(filterBean.getStart(), filterBean.getSize());
        }
        return messageService.getAllMessages();
    }

    @POST
    public Response addMessage(Message message, @Context UriInfo uriInfo) {

        Message newMessage = messageService.addMessage(message);
        String newId = String.valueOf(newMessage.getId());
        URI uri = uriInfo.getAbsolutePathBuilder().path(newId).build();
        return Response.created(uri)
                .entity(newMessage)
                .build();
    }

    @PUT
    @Path("/{messageId}")
    public Message updateMessage(@PathParam("messageId") long id, Message message) {
        message.setId(id);
        return messageService.updateMessage(message);
    }

    @DELETE
    @Path("/{messageId}")
    public void deleteMessage(@PathParam("messageId") long id) {
        messageService.removeMessage(id);
    }


    @GET
    @Path("/{messageId}")
    @ApiOperation(value = "Returns user details", notes = "Returns a complete list of users details with a date of last modification.", response = Message.class)
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "Successful retrieval of user detail", response = Message.class),
        @ApiResponse(code = 404, message = "User with given username does not exist"),
        @ApiResponse(code = 500, message = "Internal server error")
        })
    public Message getMessage(@PathParam("messageId") long id, @Context UriInfo uriInfo) {
        Message message = messageService.getMessage(id);
        message.addLink(getUriForSelf(uriInfo, message), "self");
        message.addLink(getUriForProfile(uriInfo, message), "profile");
        message.addLink(getUriForComments(uriInfo, message), "comments");

        return message;

    }

    private String getUriForComments(UriInfo uriInfo, Message message) {
        URI uri = uriInfo.getBaseUriBuilder()
                .path(MessageResource.class)
                .path(MessageResource.class, "getCommentResource")
                .path(CommentResource.class)
                .resolveTemplate("messageId", message.getId())
                .build();
        return uri.toString();
    }

    private String getUriForProfile(UriInfo uriInfo, Message message) {
        URI uri = uriInfo.getBaseUriBuilder()
             .path(ProfileResource.class)
             .path(message.getAuthor())
             .build();
        return uri.toString();
    }

    private String getUriForSelf(UriInfo uriInfo, Message message) {
        String uri = uriInfo.getBaseUriBuilder()
         .path(MessageResource.class)
         .path(Long.toString(message.getId()))
         .build()
         .toString();
        return uri;
    }




    @Path("/{messageId}/comments")
    public CommentResource getCommentResource() {
        return new CommentResource();
    }

}

InjectDemoResource.Java

package org.viquar.resources;

import javax.ws.rs.Consumes;
import javax.ws.rs.CookieParam;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;

@Path("/injectdemo")
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.TEXT_PLAIN)
public class InjectDemoResource {

    @GET
    @Path("annotations")
    public String getParamsUsingAnnotations(@MatrixParam("param") String matrixParam,
                                            @HeaderParam("authSessionID") String header,
                                            @CookieParam("name") String cookie) {
        return "Matrix param: " + matrixParam + " Header param: " + header + " Cookie param: " + cookie;
    }

    @GET
    @Path("context")
    public String getParamsUsingContext(@Context UriInfo uriInfo, @Context HttpHeaders headers) {

        String path = uriInfo.getAbsolutePath().toString();
        String cookies = headers.getCookies().toString();
        return "Path : " + path + " Cookies: " + cookies;
    }




}

CommentResource.Java

package org.viquar.resources;

import Java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.viquar.model.Comment;
import org.viquar.service.CommentService;

@Path("/")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)

public class CommentResource {

    private CommentService commentService = new CommentService();

    @GET
    public List<Comment> getAllComments(@PathParam("messageId") long messageId) {
        return commentService.getAllComments(messageId);
    }

    @POST
    public Comment addComment(@PathParam("messageId") long messageId, Comment comment) {
        return commentService.addComment(messageId, comment);
    }

    @PUT
    @Path("/{commentId}")
    public Comment updateComment(@PathParam("messageId") long messageId, @PathParam("commentId") long id, Comment comment) {
        comment.setId(id);
        return commentService.updateComment(messageId, comment);
    }

    @DELETE
    @Path("/{commentId}")
    public void deleteComment(@PathParam("messageId") long messageId, @PathParam("commentId") long commentId) {
        commentService.removeComment(messageId, commentId);
    }


    @GET
    @Path("/{commentId}")
    public Comment getMessage(@PathParam("messageId") long messageId, @PathParam("commentId") long commentId) {
        return commentService.getComment(messageId, commentId);
    }

}

MessageFilterBean.Java

package org.viquar.resources.beans;

import javax.ws.rs.QueryParam;

public class MessageFilterBean {

     private @QueryParam("year") int year;
     private @QueryParam("start") int start;
     private @QueryParam("size") int size;

     public int getYear() {
        return year;
    }
    public void setYear(int year) {
        this.year = year;
    }
    public int getStart() {
        return start;
    }
    public void setStart(int start) {
        this.start = start;
    }
    public int getSize() {
        return size;
    }
    public void setSize(int size) {
        this.size = size;
    }

}

CommentService.Java

package org.viquar.service;

import Java.util.ArrayList;
import Java.util.List;
import Java.util.Map;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.viquar.database.DatabaseClass;
import org.viquar.model.Comment;
import org.viquar.model.ErrorMessage;
import org.viquar.model.Message;

public class CommentService {

    private Map<Long, Message> messages = DatabaseClass.getMessages();

    public List<Comment> getAllComments(long messageId) {
        Map<Long, Comment> comments = messages.get(messageId).getComments();
        return new ArrayList<Comment>(comments.values());
    }

    public Comment getComment(long messageId, long commentId) {
        ErrorMessage errorMessage = new ErrorMessage("Not found", 404, "http://CosineOTC.Viquar.poc");
        Response response = Response.status(Status.NOT_FOUND)
                .entity(errorMessage)
                .build();

        Message message = messages.get(messageId);
        if (message == null) {
            throw new WebApplicationException(response);
        }
        Map<Long, Comment> comments = messages.get(messageId).getComments();
        Comment comment = comments.get(commentId);
        if (comment == null) {
            throw new NotFoundException(response);
        }
        return comment;
    }

    public Comment addComment(long messageId, Comment comment) {
        Map<Long, Comment> comments = messages.get(messageId).getComments();
        comment.setId(comments.size() + 1);
        comments.put(comment.getId(), comment);
        return comment;
    }




    public Comment updateComment(long messageId, Comment comment) {
        Map<Long, Comment> comments = messages.get(messageId).getComments();
        if (comment.getId() <= 0) {
            return null;
        }
        comments.put(comment.getId(), comment);
        return comment;
    }

    public Comment removeComment(long messageId, long commentId) {
        Map<Long, Comment> comments = messages.get(messageId).getComments();
        return comments.remove(commentId);
    }

}

MessageService.Java

package org.viquar.service;

import Java.util.ArrayList;
import Java.util.Calendar;
import Java.util.List;
import Java.util.Map;
import org.viquar.database.DatabaseClass;
import org.viquar.exception.DataNotFoundException;
import org.viquar.model.Message;

public class MessageService {

    private Map<Long, Message> messages = DatabaseClass.getMessages();

    public MessageService() {
        messages.put(1L, new Message(1, "Hello World", "ViquarKhan"));
        messages.put(2L, new Message(2, "Hello Jersey", "Shahbazkhan"));
        messages.put(3L, new Message(3, "Hello Cosine", "Snehaghosh"));
    }

    public List<Message> getAllMessages() {
        return new ArrayList<Message>(messages.values()); 
    }

    public List<Message> getAllMessagesForYear(int year) {
        List<Message> messagesForYear = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        for (Message message : messages.values()) {
            cal.setTime(message.getCreated());
            if (cal.get(Calendar.YEAR) == year) {
                messagesForYear.add(message);
            }
        }
        return messagesForYear;
    }

    public List<Message> getAllMessagesPaginated(int start, int size) {
        ArrayList<Message> list = new ArrayList<Message>(messages.values());
        if (start + size > list.size()) return new ArrayList<Message>();
        return list.subList(start, start + size); 
    }


    public Message getMessage(long id) {
        Message message = messages.get(id);
        if (message == null) {
            throw new DataNotFoundException("Message with id " + id + " not found");
        }
        return message;
    }

    public Message addMessage(Message message) {
        message.setId(messages.size() + 1);
        messages.put(message.getId(), message);
        return message;
    }

    public Message updateMessage(Message message) {
        if (message.getId() <= 0) {
            return null;
        }
        messages.put(message.getId(), message);
        return message;
    }

    public Message removeMessage(long id) {
        return messages.remove(id);
    }
}

ProfileService.Java

package org.viquar.service;

import Java.util.ArrayList;
import Java.util.List;
import Java.util.Map;
import org.viquar.database.DatabaseClass;
import org.viquar.model.Profile;

public class ProfileService {

    private Map<String, Profile> profiles = DatabaseClass.getProfiles();

    public ProfileService() {
        profiles.put("Viquar", new Profile(1L, "Viquar", "Viquar", "Khan"));
        profiles.put("Shahbaz", new Profile(2L, "Shahbaz", "Shahbaz", "Khan"));
        profiles.put("Sneha", new Profile(3L, "Sneha", "Sneha", "Ghosh"));
    }

    public List<Profile> getAllProfiles() {
        return new ArrayList<Profile>(profiles.values()); 
    }

    public Profile getProfile(String profileName) {
        return profiles.get(profileName);
    }

    public Profile addProfile(Profile profile) {
        profile.setId(profiles.size() + 1);
        profiles.put(profile.getProfileName(), profile);
        return profile;
    }

    public Profile updateProfile(Profile profile) {
        if (profile.getProfileName().isEmpty()) {
            return null;
        }
        profiles.put(profile.getProfileName(), profile);
        return profile;
    }

    public Profile removeProfile(String profileName) {
        return profiles.remove(profileName);
    }

}

SwaggerRestApp.Java

package org.viquar.swegger;

import com.wordnik.swagger.config.ConfigFactory;
import com.wordnik.swagger.config.ScannerFactory;
import com.wordnik.swagger.config.SwaggerConfig;
import com.wordnik.swagger.jaxrs.config.ReflectiveJaxrsScanner;
import com.wordnik.swagger.jaxrs.listing.ApiDeclarationProvider;
import com.wordnik.swagger.jaxrs.listing.ApiListingResource;
import com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON;
import com.wordnik.swagger.jaxrs.listing.ResourceListingProvider;
import com.wordnik.swagger.jaxrs.reader.DefaultJaxrsApiReader;
import com.wordnik.swagger.reader.ClassReaders;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.message.MessageProperties;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import org.viquar.resources.MessageResource;
import javax.annotation.PostConstruct;
import javax.ws.rs.ApplicationPath;

//@Component
@ApplicationPath("api")
public class SwaggerRestApp extends ResourceConfig {

    public SwaggerRestApp(){
        register(MessageResource.class);
        register(JacksonFeature.class);
        //register(AllExceptionMapper.class);
        register(ApiListingResource.class);
        register(ApiDeclarationProvider.class);
        register(ApiListingResourceJSON.class);
        register(ResourceListingProvider.class);

        property(MessageProperties.XML_FORMAT_OUTPUT, true);
        property(ServerProperties.TRACING, "ALL");
    }

    @PostConstruct
    /**
     * Initializes Swagger Configuration
     */
    public void initializeSwaggerConfiguration() {

        final ReflectiveJaxrsScanner scanner = new ReflectiveJaxrsScanner();
        scanner.setResourcePackage("org.viquar);
        ScannerFactory.setScanner(scanner);
        ClassReaders.setReader(new DefaultJaxrsApiReader());
        final SwaggerConfig config = ConfigFactory.config();
        config.setApiVersion("1.0");
        config.setBasePath("http://localhost:8080/messenger/cosineotc/api/v1");

    }
}

 enter image description here

En raison du problème de limite, le prochain commentaire continue .....

1
vaquar khan

Pour compléter la réponse de tbraun: 

Voici one avec une démonstration claire (erreurs, annotations, etc ...), Et une autre .

Je vous suggère de vous référer à la doc: swagger doc aussi.

Soyez prudent en prenant la dernière version car certaines propriétés swagger ne fonctionnent pas avec certaines versions swagger, comme "apisOrder" pour trier l'API par nom.

Lorsque vous testez votre APi, vous pouvez utiliser l'interface utilisateur swagger.

J'espère que cela vous aidera.

0
hamdalaye

Partie 2 continue ...

Maintenant, vous devez configurer Webapp, créer un dossier avec le nom suivant et copier le contenu à l'intérieur du dossier. 

  • Copier CSS à l'intérieur de JerseyRestSSweggerPoc\src\main\webapp\css 

  • Copier des polices à l'intérieur de JerseyRestSSweggerPoc\src\main\webapp\fonts

  • Copier des images dans JerseyRestSSweggerPoc\src\main\webapp\images

  • Copier lang à l'intérieur de JerseyRestSSweggerPoc\src\main\webapp\lang

  • Copier la lib à l'intérieur de JerseyRestSSweggerPoc\src\main\webapp\lib

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Swagger UI</title>
  <link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32" />
  <link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16" />
  <link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
  <link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
  <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
  <link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
  <link href='css/print.css' media='print' rel='stylesheet' type='text/css'/>
  <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
  <script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
  <script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
  <script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
  <script src='lib/handlebars-2.0.0.js' type='text/javascript'></script>
  <script src='lib/underscore-min.js' type='text/javascript'></script>
  <script src='lib/backbone-min.js' type='text/javascript'></script>
  <script src='swagger-ui.js' type='text/javascript'></script>
  <script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
  <script src='lib/marked.js' type='text/javascript'></script>
  <script src='lib/swagger-oauth.js' type='text/javascript'></script>

  <!-- Some basic translations -->
  <!-- <script src='lang/translator.js' type='text/javascript'></script> -->
  <!-- <script src='lang/ru.js' type='text/javascript'></script> -->
  <!-- <script src='lang/en.js' type='text/javascript'></script> -->

  <script type="text/javascript">
    $(function () {
      var url = window.location.search.match(/url=([^&]+)/);
      if (url && url.length > 1) {
        url = decodeURIComponent(url[1]);
      } else {
        url = "http://localhost:8080/messenger/api/v1/api-docs";
      }

      // Pre load translate...
      if(window.SwaggerTranslator) {
        window.SwaggerTranslator.translate();
      }
      window.swaggerUi = new SwaggerUi({
        url: url,
        dom_id: "swagger-ui-container",
        supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
        onComplete: function(swaggerApi, swaggerUi){
          if(typeof initOAuth == "function") {
            initOAuth({
              clientId: "your-client-id",
              clientSecret: "your-client-secret",
              realm: "your-realms",
              appName: "your-app-name", 
              scopeSeparator: ","
            });
          }

          if(window.SwaggerTranslator) {
            window.SwaggerTranslator.translate();
          }

          $('pre code').each(function(i, e) {
            hljs.highlightBlock(e)
          });

          addApiKeyAuthorization();
        },
        onFailure: function(data) {
          log("Unable to Load SwaggerUI");
        },
        docExpansion: "none",
        apisSorter: "alpha",
        showRequestHeaders: false
      });

      function addApiKeyAuthorization(){
        var key = encodeURIComponent($('#input_apiKey')[0].value);
        if(key && key.trim() != "") {
            var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query");
            window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
            log("added key " + key);
        }
      }

      $('#input_apiKey').change(addApiKeyAuthorization);

      // if you have an apiKey you would like to pre-populate on the page for demonstration purposes...
      /*
        var apiKey = "myApiKeyXXXX123456789";
        $('#input_apiKey').val(apiKey);
      */

      window.swaggerUi.load();

      function log() {
        if ('console' in window) {
          console.log.apply(console, arguments);
        }
      }
  });
  </script>
</head>

<body class="swagger-section">
<div id='header'>
  <div class="swagger-ui-wrap">
    <a id="logo" href="http://swagger.io">swagger</a> -->
    <form id='api_selector'>
      <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
      <div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
      <div class='input'><a id="explore" href="#" data-sw-translate>Explore</a></div>
    </form>
  </div>
</div>

<div id="message-bar" class="swagger-ui-wrap" data-sw-translate>&nbsp;</div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>

Index.jsp

<html>
<head> 
   <meta charset="UTF-8"> 
   <title>Swagger UI</title> 
   <link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32" /> 
   <link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16" /> 
   <link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/> 
   <link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/> 
   <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/> 
   <link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/> 
   <link href='css/print.css' media='print' rel='stylesheet' type='text/css'/> 
   <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script> 
   <script src='lib/jquery.slideto.min.js' type='text/javascript'></script> 
   <script src='lib/jquery.wiggle.min.js' type='text/javascript'></script> 
   <script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script> 
   <script src='lib/handlebars-2.0.0.js' type='text/javascript'></script> 
   <script src='lib/underscore-min.js' type='text/javascript'></script> 
   <script src='lib/backbone-min.js' type='text/javascript'></script> 
   <script src='swagger-ui.js' type='text/javascript'></script> 
   <script src='lib/highlight.7.3.pack.js' type='text/javascript'></script> 
   <script src='lib/marked.js' type='text/javascript'></script> 
   <script src='lib/swagger-oauth.js' type='text/javascript'></script> 

   <!-- Some basic translations --> 
   <!-- <script src='lang/translator.js' type='text/javascript'></script> --> 
   <!-- <script src='lang/ru.js' type='text/javascript'></script> --> 
   <!-- <script src='lang/en.js' type='text/javascript'></script> --> 


   <script type="text/javascript"> 
     $(function () { 
       var url = window.location.search.match(/url=([^&]+)/); 
       if (url && url.length > 1) { 
         url = decodeURIComponent(url[1]); 
       } else { 
         url = "http://petstore.swagger.io/v2/swagger.json"; 
       } 

       // Pre load translate... 
       if(window.SwaggerTranslator) { 
         window.SwaggerTranslator.translate(); 
       } 
       window.swaggerUi = new SwaggerUi({ 
         url: url, 
         dom_id: "swagger-ui-container", 
         supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'], 
         onComplete: function(swaggerApi, swaggerUi){ 
           if(typeof initOAuth == "function") { 
             initOAuth({ 
               clientId: "your-client-id", 
               clientSecret: "your-client-secret", 
               realm: "your-realms", 
               appName: "your-app-name",  
               scopeSeparator: "," 
             }); 
           } 

           if(window.SwaggerTranslator) { 
             window.SwaggerTranslator.translate(); 
           } 

           $('pre code').each(function(i, e) { 
             hljs.highlightBlock(e) 
           }); 

           addApiKeyAuthorization(); 
         }, 
         onFailure: function(data) { 
           log("Unable to Load SwaggerUI"); 
         }, 
         docExpansion: "none", 
         apisSorter: "alpha", 
         showRequestHeaders: false 
       }); 

       function addApiKeyAuthorization(){ 
         var key = encodeURIComponent($('#input_apiKey')[0].value); 
         if(key && key.trim() != "") { 
             var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query"); 
             window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth); 
             log("added key " + key); 
         } 
       } 

       $('#input_apiKey').change(addApiKeyAuthorization); 

       // if you have an apiKey you would like to pre-populate on the page for demonstration purposes... 
       /* 
         var apiKey = "myApiKeyXXXX123456789"; 
         $('#input_apiKey').val(apiKey); 
       */ 

       window.swaggerUi.load(); 

       function log() { 
         if ('console' in window) { 
           console.log.apply(console, arguments); 
         } 
       } 
   }); 
   </script> 
 </head> 

<body>
    <h2>Jersey RESTful Web Application!</h2>
    <p><a href="webapi/myresource">Jersey resource</a>
    <p>Visit <a href="http://jersey.Java.net">Project Jersey website</a>
    for more information on Jersey!



</body>
</html>

o2c.html

<script>
var qp = null;
if(window.location.hash) {
  qp = location.hash.substring(1);
}
else {
  qp = location.search.substring(1);
}
qp = qp ? JSON.parse('{"' + qp.replace(/&/g, '","').replace(/=/g,'":"') + '"}',
  function(key, value) {
    return key===""?value:decodeURIComponent(value) }
  ):{}

if (window.opener.swaggerUi.tokenUrl)
    window.opener.processOAuthCode(qp);
else
    window.opener.onOAuthComplete(qp);

window.close();
</script>

J'espère que cela vous aidera.

URL d'accès

http://localhost:8080/messenger//api/v1/messages/1
**Swegger** :
http://localhost:8080/messenger/
http://localhost:8080/jersey-swagger/rest/api-docs
http://localhost:8080/jersey-swagger/#!/employees/createEmployee




http://localhost:8080/messenger//api/v1/api-docs
http://localhost:8080/messenger/#!/messages/getMessage
http://localhost:8080/messenger//api/v1/messages/1


{
"author":"Viquar Khan","created":"2015-07-31T16:35:43.498",
"id":1,
"links":[
{"link":"http://localhost:8080/JerseyRestPoc//api/v1/messages/1","rel":"self"},
{"http://localhost:8080/JerseyRestPoc//api/v1/profiles/Viquar%20Khan","rel":"profile"},
{"link":"http://localhost:8080/JerseyRestPoc/api/v1/messages/1/comments/","rel":"comments"}
],
"message":"Hello World"
}

À l'intérieur de MessageResource.Java, j'ai ajouté les annotations suivantes à Swagger

@Api (valeur = "/ messages", description = "Opération sur les ordres")

0
vaquar khan