API получения REST-контента

В этой статье вы узнаете, как создавать RESTful-сервисы в DC CMS.

Чтобы получить доступ к контенту, вы можете использовать API для получения REST-контента.

Убедитесь, что запрос содержит параметр dcSite, чтобы указать значение проекта. Поскольку API для получения контента настроены под конкретные проекты, необходимо предоставлять информацию о проекте при каждом запросе.


Вот пример получения элемента из хранилища контента:

http://localhost:8080/api/1/site/content_store/item.json?url=/site/website/index.xml&dcSite=mysite

Примеры

Ниже приведены несколько примеров создания RESTful сервисов в DC CMS.

Рендеринг компонентов страницы в формате JSON

Контент как сервис (CaaS) - широко используемая необходимость в современном многоканальном мире. Обычно варианты использования CaaS требуют, чтобы контент был лишен форматной разметки (presentation markup), чтобы клиент мог представить контент так, как он пожелает. Иногда клиенты также могут захотеть получить предварительно отрендеренный контент. Ниже представлен простой пример REST (один сценарий для контроллера REST на основе Groovy), который предлагает метод отображения всех компонентов, связанных с страницей.

Шаг 1: Создание REST контроллера

1. В боковой панели перейдите в раздел Скрипты > scripts > rest, щелкните правой кнопкой мыши и выберите Новый контроллер.

Изображение статьи

2. Введите get-rendered-components.get в качестве имени контроллера.

3. Добавьте этот код в контроллер:

import java.io.ByteArrayOutputStream
import java.io.IOException
import java.io.PrintWriter

import javax.servlet.Filter
import javax.servlet.FilterChain
import javax.servlet.FilterConfig
import javax.servlet.ServletException
import javax.servlet.ServletOutputStream
import javax.servlet.ServletRequest
import javax.servlet.ServletResponse
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpServletResponseWrapper
import javax.servlet.WriteListener
import groovy.util.XmlSlurper

def result = [:]
def targetPage = params.pageId

if (targetPage != null) {
        result.page = targetPage

        def pageItem = siteItemService.getSiteItem(targetPage)

        if (pageItem != null) {
                def componentPaths = pageItem.queryValues("//include")
                result.components = []

                if (componentPaths != null) {
                        componentPaths.each { componentPath ->
                                if (componentPath.endsWith(".xml") && !componentPath.startsWith("/site/website") ) {
                                        logger.info("Including component ${componentPath} into JSON response")

                                        def component = [:]
                                        component.id = componentPath

                                        // wrap the response to capture the output
                                        def wrappedResponse = new CapturingResponseWrapper(response)

                                        // "include" the page that does the actual work
                                        request.getRequestDispatcher("/dc-controller/component?path=" + componentPath).include(request, wrappedResponse)

                                        // get the captured output, parse it and prepare the actual response
                                        def capturedOut = wrappedResponse.getCaptureAsString()

                                        component.markup = capturedOut

                                        result.components.add(component)
                                }
                        }
                } else {
                        result.message = "No components found"
                }
        } else {
                result.message = "Page '${targetPage}` not found"
        }
} else {
        result.message = "Parameter pageId is required."
}

return result

protected class CapturingResponseWrapper extends HttpServletResponseWrapper {

        private final ByteArrayOutputStream capture
        private ServletOutputStream output
        private PrintWriter writer

        public CapturingResponseWrapper(HttpServletResponse response) {
                super(response)
                capture = new ByteArrayOutputStream(response.getBufferSize())
        }

        @Override
        public ServletOutputStream getOutputStream() {
                if (writer != null) {
                        throw new IllegalStateException("getWriter() has already been called on this response.")
                }

                if (output == null) {
                        output = new ServletOutputStream() {

                                @Override
                                public void write(int b) throws IOException {
                                        capture.write(b)
                                }

                                @Override
                                public void flush() throws IOException {
                                        capture.flush()
                                }

                                @Override
                                public void close() throws IOException {
                                        capture.close()
                                }

                                @Override
                                public void setWriteListener(WriteListener writeListener) {
                                }

                                @Override
                                public boolean isReady() {
                                        return true
                                }
                        }
                }

                return output
        }

        @Override
        public PrintWriter getWriter() throws IOException {
                if (output != null) {
                        throw new IllegalStateException("getOutputStream() has already been called on this response.")
                }

                if (writer == null) {
                        writer = new PrintWriter(new OutputStreamWriter(capture, getCharacterEncoding()))
                }

                return writer
        }

        @Override
        public void flushBuffer() throws IOException {
                super.flushBuffer()

                if (writer != null) {
                        writer.flush()
                }
                else if (output != null) {
                        output.flush()
                }
        }

        public byte[] getCaptureAsBytes() throws IOException {
                if (writer != null) {
                        writer.close()
                }
                else if (output != null) {
                        output.close()
                }

                return capture.toByteArray()
        }

        public String getCaptureAsString() throws IOException {
                return new String(getCaptureAsBytes(), getCharacterEncoding())
        }

}

Copy-icon

Шаг 2: Выполнение сервиса

Откройте браузер и перейдите по следующему URL-адресу: http://localhost:8080/api/1/services/get-rendered-components.json?pageId=/site/website/index.xml

Получение названий сайтов, запущенных в CMS Engine

В этом примере мы создадим простой RESTful сервис, который возвращает список сайтов, запущенных в CMS Engine.

Шаг 1: Создание REST контроллера

1. В боковой панели перейдите в раздел Скрипты > scripts > rest, щелкните правой кнопкой мыши и выберите Новый контроллер.

Изображение статьи

2. Введите get-sites.get в качестве имени контроллера.

3. Добавьте этот код в контроллер:

def siteContextManager = applicationContext["dc.siteContextManager"]
def siteContextList = siteContextManager.listContexts()
def siteNames = []

siteContextList.each { siteContext ->
    def name = siteContext.getSiteName()
    siteNames.add(name)
}

return siteNames

Copy-icon

Шаг 2: Выполнение сервиса

Откройте браузер и перейдите по следующему URL-адресу: http://localhost:8080/api/1/services/get-sites.json

Получение страниц для сайта

В этом примере мы создадим простой RESTful сервис, который возвращает список страниц на сайте. Сервис параметризован, чтобы позволить вызывающему установить начальную точку и глубину.

Шаг 1: Создание REST контроллера

1. В боковой панели перейдите в раздел Скрипты > scripts > rest, щелкните правой кнопкой мыши и выберите Новый контроллер.

Изображение статьи

2. Введите get-pages.get в качестве имени контроллера.

3. Добавьте этот код в контроллер:

def pathParam = (params.path != null) ? params.path : ""
def depthParam = (params.depth != null) ? params.depth.toInteger() : 0

def path = "/site/website" + pathParam
def depth = depthParam != 0 ? depthParam : 2

def navItems = [:]
def siteDir = siteItemService.getSiteTree(path, depth)

if(siteDir) {
    def dirs = siteDir.childItems
    dirs.each { dir ->
            def dirName = dir.getStoreName()
            def dirItem = siteItemService.getSiteItem("/site/website/${dirName}/index.xml")

            if (dirItem != null) {
                def dirDisplayName = dirItem.queryValue('internal-name')

                navItems.put(dirName, dirDisplayName)
            }
   }
}

return navItems

Copy-icon

Шаг 2: Выполнение сервиса

Откройте браузер и перейдите по следующему URL-адресу: http://localhost:8080/api/1/services/get-pages.json

Связанные статьи

API