{"id":44550,"date":"2017-01-17T14:07:29","date_gmt":"2017-01-17T08:37:29","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=44550"},"modified":"2017-01-17T15:20:25","modified_gmt":"2017-01-17T09:50:25","slug":"how-to-integrate-rabbitmq-using-spring","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/how-to-integrate-rabbitmq-using-spring\/","title":{"rendered":"How To Integrate RabbitMQ using Spring?"},"content":{"rendered":"<p align=\"left\"><span style=\"font-size: medium;\">In this blog, we will see two different implementations of RabbitMQ, but before going to the implementation part let&#8217;s take a brief intro of some prerequisites.<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>JMS <\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">The Java Message Service (JMS) is a Message Oriented Middleware Java API that supports the formal communication between software components. It allows applications to create, send, receive, and read messages in such a way that communication is loosely coupled, reliable and asynchronous. <\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>AMQP <\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">The Advanced Message Queuing Protocol (AMQP) is an open standard for message-oriented middlewares. AMQP creates full functional interoperability between conforming clients and messaging middleware servers (also called &#8220;brokers&#8221;). <\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>What is RabbitMQ? <\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">RabbitMQ is an open source message-oriented middleware (also called &#8220;brokers&#8221;) that implements the Advanced Message Queuing Protocol (AMQP). <\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">Benefits of using RabbitMQ<\/span><\/p>\n<ol>\n<li><span style=\"font-size: medium;\">Robust messaging for applications <\/span><\/li>\n<li>Runs on all major operating systems<\/li>\n<li><span style=\"font-size: medium;\">Supports a huge number of developer platforms <\/span><\/li>\n<li><span style=\"font-size: medium;\">Open source and commercially supported<\/span><\/li>\n<li>Easy to use<\/li>\n<\/ol>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Installation Steps<\/b><\/span><\/p>\n<ol>\n<li><span style=\"font-size: medium;\">You can use below link to install RabbitMQ Server in your computer.<\/span><\/li>\n<\/ol>\n<p style=\"padding-left: 30px;\" align=\"left\"><span style=\"font-size: medium;\">https:\/\/www.rabbitmq.com\/install-debian.html .<\/span><\/p>\n<p style=\"padding-left: 30px;\" align=\"left\"><span style=\"font-size: medium;\">Now use below command to enable RabbitMQ Managment Plugin. <\/span><\/p>\n<p style=\"padding-left: 30px;\" align=\"left\"><em><span style=\"font-size: medium;\">rabbitmq-plugins enable rabbitmq_management<\/span><\/em><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">2. Check\u00a0<\/span><em style=\"font-size: 1rem;\"><span style=\"font-size: medium;\">localhost:15672<\/span><\/em><\/p>\n<p style=\"padding-left: 30px;\" align=\"left\">Default <em>user name=guest<\/em><\/p>\n<p style=\"padding-left: 30px;\" align=\"left\"><span style=\"font-size: medium;\">Default <em>password=guest<\/em><\/span><\/p>\n<p style=\"padding-left: 30px;\" align=\"left\"><span style=\"font-size: medium;\">For complete reference Please Visit https:\/\/www.rabbitmq.com\/management.html.<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">Now you&#8217;re ready to use RabbitMQ.<\/span><\/p>\n<p align=\"left\"><strong><span style=\"font-size: medium;\">RabbitMQ Use Case<\/span><\/strong><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">Let&#8217;s take a scenario in which we have to perform multiple different tasks by events we pass in the queue. We have Producer (who sends a message) and Consumer (who receives a message).<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">Consumer passes a message to the EventHandler Class. It is explained more clearly in the following steps. <\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">Here we will see two different implementations in Spring. First JMS Base integration and other Spring particular AMQP base integration.<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><strong>JMS Base Integration:<\/strong><br \/>\n<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 1.1: Adding Library Dependency <\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">To get started with RabbitMQ Java AMQP, it is recommended to use a dependency management system. <\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">The maven dependency is given below: <\/span><\/p>\n<p>[code language=&#8221;xml&#8221;]<br \/>\n&lt;dependency&gt;<br \/>\n\t&lt;groupId&gt;com.rabbitmq&lt;\/groupId&gt;<br \/>\n\t&lt;artifactId&gt;amqp-client&lt;\/artifactId&gt;<br \/>\n\t&lt;version&gt;4.0.0&lt;\/version&gt;<br \/>\n&lt;\/dependency&gt;<br \/>\n[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">Alternatively, if you&#8217;re using Gradle: <\/span><\/p>\n<p>[code language=&#8221;xml&#8221;]<br \/>\ndependencies {<br \/>\n  compile &#8216;com.rabbitmq:amqp-client:4.0.0&#8217;<br \/>\n}<br \/>\n[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 1.2: Create Connector Class<\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">Now, we need to create an abstract Connector class. Basic implementation of RabbitMQ is same for Producer as well as Consumer. We can generalize our code in the connector class and Producer\/Consumer will have to inherit this class.<\/span><\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\npublic abstract class Connector {<br \/>\n\tprotected Channel myChannel;<br \/>\n\tprotected Connection connection;<br \/>\n\tprotected String queueName;<\/p>\n<p>\tpublic Connector(String queueName) throws IOException,TimeoutException {<br \/>\n\t\tthis.queueName=queueName;<br \/>\n\t\tConnectionFactory connectionFactory = new ConnectionFactory();<br \/>\n\t\t\/\/ Hostname of your rabbitmq server<br \/>\n\t\tconnectionFactory.setHost(&quot;localhost&quot;);<br \/>\n\t\t\/\/ getting a connection<br \/>\n\t\tconnection = connectionFactory.newConnection();<\/p>\n<p>\t\t\/*this will create a new channel, using an internally allocated channel number or we can say it will simply declare a queue for this channel. If queue does not exist.*\/<br \/>\n\t\tmyChannel= connection.createChannel();<\/p>\n<p>\t\tmyChannel.queueDeclare(queueName, false, false, false, null);<br \/>\n\t}<\/p>\n<p>\tpublic void close() throws IOException, TimeoutException {<br \/>\n\t\tthis.myChannel.close();<br \/>\n\t\tthis.connection.close();<br \/>\n\t}<br \/>\n}<br \/>\n[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 1.3: Create Producer<\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">A program that sends messages is a Producer.<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">It has to inherit connector class so that producer is able to communicate with the queue.<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>sendMessage (Serializable object)<\/b> method will send the serializable data to the queue. <\/span><\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\npublic class Producer extends  Connector {<br \/>\n    public Producer(String queueName) throws IOException, TimeoutException{<\/p>\n<p>        super(queueName);<br \/>\n    }<\/p>\n<p>    public void sendMessage(Serializable object) throws IOException {<br \/>\n        channel.basicPublish(&quot;&quot;,queueName, null, SerializationUtils.serialize(object));<br \/>\n    }<br \/>\n}<br \/>\n[\/code]<\/p>\n<p align=\"left\">\u00a0<span style=\"font-size: medium;\"><b>Step 1.4: Create Consumer<\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">A consumer is a program that mostly waits to receive messages. I<\/span>t has to inherit connector class so that Consumer is able to communicate with the queue.<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">Now the consumer will receive the serialized data (message) so we have to deserialize this data before use it.<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>public void handleDelivery(String consumerTag, Envelope env, BasicProperties props, byte[] body).<\/b> <\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">This method will receive the message and body is the serialized data which we will deserialize before using it.<\/span><\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\npublic class QueueConsumer extends Connector implements Runnable, Consumer { <\/p>\n<p>    public QueueConsumer(String queueName) throws IOException, TimeoutException {<br \/>\n        super(queueName);<br \/>\n    } <\/p>\n<p>    public void run() {<br \/>\n        try {<br \/>\n            \/\/ start consuming messages. Auto acknowledge messages.<br \/>\n            channel.basicConsume(queueName, true, this);<br \/>\n        } catch (IOException e) {<br \/>\n            e.printStackTrace();<br \/>\n        }<br \/>\n    }<br \/>\n    public void handleConsumeOk(String info) {<br \/>\n       \/\/Called when the consumer is registered. <\/p>\n<p>    } <\/p>\n<p>    \/\/  Called when new message is available. <\/p>\n<p>    public void handleDelivery(String info, Envelope env, BasicProperties props, byte[] body)<br \/>\n            throws IOException {<br \/>\n        Map map = (HashMap) SerializationUtils.deserialize(body);<br \/>\n        EventHandler.handler((Events) map.get(&quot;event&quot;), map.get(&quot;message&quot;));<br \/>\n    } <\/p>\n<p>    public void handleCancel(String info) {<br \/>\n       \/\/Called when the consumer is canceled..<br \/>\n    } <\/p>\n<p>    public void handleCancelOk(String info) {<br \/>\n    } <\/p>\n<p>    public void handleRecoverOk(String info) {<br \/>\n    } <\/p>\n<p>    public void handleShutdownSignal(String info, ShutdownSignalException exception) {<br \/>\n    }<br \/>\n}<br \/>\n[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 1.5: Create enum Events<\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">These are the events which will be used to decide which task to perform.<\/span><\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\nenum Events {<br \/>\nEvent1,Event2;<\/p>\n<p>}<br \/>\n[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 1.6: Create class EventHandler<\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">This class will handle all the events you want to trigger whenever consumer consumes a message.<\/span><\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\npublic class EventHandler {<br \/>\n    static void handler(Events event, Object message) {<br \/>\n        switch (event) {<br \/>\n        case Event1:<br \/>\n            System.out.println(&quot;publish 1 event&quot; + message);<br \/>\n            break;<br \/>\n        case Event2:<br \/>\n            System.out.println(&quot;publish event 2&quot; + message);<br \/>\n            break;<br \/>\n        }<br \/>\n    }<br \/>\n}<\/p>\n<p>[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 1.7: Create a constant Class<\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">This class will have the queue name.<\/span><\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\npublic final class Constants {<br \/>\n    public static final String queueName = &quot;queueName&quot;; <\/p>\n<p>}<br \/>\n[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 1.8: Create Service Class EventPublisherService<\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">When the EventPublisherService bean is created at that moment Consumer, producer instant will be created and the consumer thread will be started. <\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>public void publishEvent(Events event, Object messages) <\/b>method will create a message and that will be sent to the queue.<\/span><\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\n@Service<br \/>\npublic class EventPublisherService {<br \/>\n    final private Producer producer; <\/p>\n<p>    EventPublisherService() throws IOException, TimeoutException {<br \/>\n        QueueConsumer consumer = new QueueConsumer(Constants.queueName);<br \/>\n        Thread consumerThread = new Thread(consumer);<br \/>\n        consumerThread.start();<br \/>\n        producer = new Producer(Constants.queueName);<br \/>\n    } <\/p>\n<p>    public void publishEvent(Events event, Object messages) throws IOException, TimeoutException { <\/p>\n<p>        HashMap&lt;String, Object&gt; message = new HashMap&lt;String, Object&gt;();<br \/>\n        message.put(&quot;event&quot;, event);<br \/>\n        message.put(&quot;message&quot;, messages);<br \/>\n        producer.sendMessage(message);<br \/>\n    }<br \/>\n}<br \/>\n[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 1.9: Create Controller <\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">We just have to pass Event Type and message to <b>publishEvent (Events, message) <\/b>method of <b>EventPublisherService<\/b> and rest is handled by it.<\/span><\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\n@Controller<br \/>\n@RequestMapping(&quot;\/&quot;)<br \/>\npublic class UserController {<br \/>\n    @Autowired<br \/>\n    EventPublisherService eventPublisherService;<br \/>\n    @RequestMapping(&quot;\/rabbitMq&quot;)<br \/>\n    public ModelAndView welcome() throws IOException, TimeoutException {<br \/>\n        Integer message1 = 11111;<br \/>\n        eventPublisherService.publishEvent(Events.Event1, message1);<br \/>\n        String message2 = &quot;Implementing RabbitMQ&quot;;<br \/>\n        eventPublisherService.publishEvent(Events.Event2, message2);<br \/>\n        return new ModelAndView(&quot;index&quot;, &quot;message&quot;, &quot;Implemented&quot;);<br \/>\n    }<br \/>\n}<\/p>\n<p>[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Spring Specific Implementation<\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">There will be no Producer and consumer classes in this implementation.\u00a0<\/span>We only need to use below command\u00a0to send message.<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">template.convertAndSend(Constants.queueName,message);<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">And @RabbitListener(queues = \u201cqueueName\u201d) Annotation to receive a message. It is explained more clearly in the following steps:<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 2.1: Adding Library Dependency <\/b><\/span><\/p>\n<p>[code language=&#8221;xml&#8221;]<br \/>\n&lt;dependency&gt;<br \/>\n      &lt;groupId&gt;org.springframework.amqp&lt;\/groupId&gt;<br \/>\n      &lt;artifactId&gt;spring-rabbit&lt;\/artifactId&gt;<br \/>\n      &lt;version&gt;1.4.5.RELEASE&lt;\/version&gt;<br \/>\n&lt;\/dependency&gt;<br \/>\n[\/code]<\/p>\n<p>alternatively for Gradle<\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\ncompile group: &#8216;org.springframework.amqp&#8217;, name: &#8216;spring-rabbit&#8217;, version: &#8216;1.4.5.RELEASE&#8217;<br \/>\n[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 2.2: Create a configuration class named RabbitMqConfiguration<\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">Here we will create all the mandatory beans which are required By RabbitMQ.<\/span><\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\n@Configuration<br \/>\npublic class RabbitMqConfiguration {<br \/>\n    @Bean<br \/>\n    public ConnectionFactory connectionFactory() {<br \/>\n        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(&quot;localhost&quot;);<br \/>\n        return connectionFactory;<br \/>\n    }<\/p>\n<p>    @Bean<br \/>\n    public AmqpAdmin amqpAdmin() {<br \/>\n        return new RabbitAdmin(connectionFactory());<br \/>\n    }<\/p>\n<p>    @Bean<br \/>\n    public RabbitTemplate rabbitTemplate() {<br \/>\n        return new RabbitTemplate(connectionFactory());<br \/>\n    }<\/p>\n<p>    @Bean<br \/>\n    public Queue myQueue() {<br \/>\n        return new Queue(Constants.queueName);<br \/>\n    }<br \/>\n     @Bean(name=&quot;rabbitListenerContainerFactory&quot;)<br \/>\n     public SimpleRabbitListenerContainerFactory         rabbitListenerContainerlistenerFactory(){<br \/>\n      SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();<br \/>\n      factory.setConnectionFactory(connectionFactory());<br \/>\n      return factory;<br \/>\n     }<\/p>\n<p>}<br \/>\n[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 2.3: Repeat Steps<\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">The <span style=\"font-family: Liberation Serif,serif;\"><span style=\"color: #000000;\">Events enum<\/span>, <\/span><span style=\"color: #000000;\"><span style=\"font-family: Liberation Serif,serif;\">EventHandler class, Constants class and <\/span><\/span><span style=\"color: #000000;\"><span style=\"font-family: Liberation Serif,serif;\">controller <\/span><\/span><span style=\"color: #000000;\"><span style=\"font-family: Liberation Serif,serif;\">Class<\/span><\/span><b>\u00a0<\/b>are same as created in Step 1.5,1.6,1.7 and 1.9.<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 2.4: Create EventPublisherService<\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">EventPublisherService will create a message and then send it to the queue using template.convertAndSend(Constants.queueName,message); <\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">this service Act like a producer.<\/span><\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\n@Service<br \/>\npublic class EventPublisherService {<br \/>\n    @Autowired<br \/>\n    AmqpTemplate template;<br \/>\n    public void publishEvent(Events event, Object messages) throws IOException, TimeoutException {<br \/>\n        Map&lt;String, Object&gt; message = new HashMap&lt;String, Object&gt;();<br \/>\n        message.put(&quot;event&quot;, event);<br \/>\n        message.put(&quot;message&quot;, messages);<br \/>\n        template.convertAndSend(Constants.queueName,message);<br \/>\n    }<\/p>\n<p>}<br \/>\n[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step 2.5 Create Listener Class or consumer named RabbitMqMessageListener <\/b><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">This is the Listener class or Consumer whenever Producer sends a message to the queue this class will receive it and the only method having annotation @RabbitListener(queues = Constants.queueName) will receive the messages.<\/span><\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\n@EnableRabbit<br \/>\n@Component<br \/>\npublic class RabbitMqMessageListener {<br \/>\n    @RabbitListener(queues = Constants.queueName)<br \/>\n    public void processQueue(Map&lt;String, Object&gt; message) {<br \/>\n        EventHandler.handler((Events) message.get(&quot;event&quot;), message.get(&quot;message&quot;));<br \/>\n    }<br \/>\n[\/code]<\/p>\n<p align=\"left\"><span style=\"font-size: medium;\"><b>Step <\/b><b>2<\/b><b>.<\/b><b>6<\/b><b>: <\/b>This is an additional step which depends on the use case. In the preceding step, I have used view(index.jsp) in the controller. So now you have to create the view(index.jsp) in<em> webapp\/WEB-INF\/views. <\/em><\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">Finally use the command:<em> mvn jetty:run<\/em> in your root directory of a project to run the project.<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">Hope this will Help. Thank You.<\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">You can find the source code at following git repo&#8217;s <\/span><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">basic RabbitMq JMS integration<\/span><\/p>\n<p align=\"left\"><a href=\"https:\/\/github.com\/amitraturi36\/RabbitMqSpringIntegration.git\"><span style=\"font-size: medium;\">https:\/\/github.com\/amitraturi36\/RabbitMqSpringIntegration.git<\/span><\/a><\/p>\n<p align=\"left\"><span style=\"font-size: medium;\">spring specific AMQP Integration<\/span><\/p>\n<p align=\"left\"><a href=\"https:\/\/github.com\/amitraturi36\/SpringRabbitMQIntegrationExample.git\"><span style=\"font-size: medium;\">https:\/\/github.com\/amitraturi36\/SpringRabbitMQIntegrationExample.git<\/span><\/a><\/p>\n<p align=\"left\">Also See:<\/p>\n<p align=\"left\"><a title=\"Sending messages with RabbitMQ\" href=\"http:\/\/www.tothenew.com\/blog\/sending-scheduleddelayed-messages-with-rabbitmq-through-java-client\/\">Sending Scheduled\/delayed messages with RabbitMQ through java client<\/a><\/p>\n<p align=\"left\"><a title=\"Integrating Rabbit MQ with Grails\" href=\"http:\/\/www.tothenew.com\/blog\/few-simple-steps-for-integrating-rabbit-mq-with-grails\/#sthash.19XI1CPf.dpuf\">Few Simple steps for integrating Rabbit MQ with Grails\u00a0<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog, we will see two different implementations of RabbitMQ, but before going to the implementation part let&#8217;s take a brief intro of some prerequisites. JMS The Java Message Service (JMS) is a Message Oriented Middleware Java API that supports the formal communication between software components. It allows applications to create, send, receive, and [&hellip;]<\/p>\n","protected":false},"author":1032,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":15},"categories":[7,446,1],"tags":[1077,4383,4382],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/44550"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1032"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=44550"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/44550\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=44550"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=44550"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=44550"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}