Message Boards

Headless API - Is there a WebServerServlet equivalent?

thumbnail
Christopher Dawson, modified 3 Years ago.

Headless API - Is there a WebServerServlet equivalent?

New Member Posts: 11 Join Date: 2/27/12 Recent Posts

Greetings:

Hoping to get an answer regarding how to access file content from the document library via the headless api?

We are running an independent SPA that is connecting to LR via the headless api with OAuth2/JWT. Since LR at this point is effectively stateless, I am wondering what the recommended approach is for delivering content from the document library?

I am attempting to return links to images as part of my JSON payload and had started off by including an image preview url. I was clearly thinking old-school - leveraging the WebServerServlet behind the /documents web.xml definition - because now there is no session information coming from the SPA -> API so every image request is getting redirected to the sign in page.

I watched the DevCon presentation by Javier G. (thx for that!) and the topic was touched on briefly in terms of whether or not to embed content directly via nested fields. But I did not hear a definitive answer for larger files (or any files for that matter).

I have browsed through the LR /o/headless-delivery/v1.0 endpoints - and did see an Image schema entity. However I can find no relationship between that and any of the resources available from that endpoint. The Document schema includes a contentUrl - but again that is going through the WebServerServlet.

Options that occur to me:

  1. Adapted Images. I do notice that as part of the document payload from a call to /o/headless-delivery/v1.0/sites/{siteId}/documents that I am getting back an object containing adaptedImages e.g.  /o/adaptive-media/image/12345/Preview-1000x0/AnImage-123.png?t=1538761582000
    However I am unable to retrieve these - nor does the path appear to match any of the available Rest APIs via API Explorer
  2. Provide my own signed URL to S3 outside of the document library to allow timed access?
  3. Incorporate some authentication token in every image request?

Thanks in advance for any information you can provide on the matter.

Sincerely,

Chris D.

thumbnail
Christopher Dawson, modified 3 Years ago.

RE: Headless API - Is there a WebServerServlet equivalent?

New Member Posts: 11 Join Date: 2/27/12 Recent Posts

As a follow up to this. I attempted to add my own API endpoint to return a file stream - however this does not appear to be supported within the 7.3.5 ga6 version of REST Builder: 

# rest-opeenapi.yaml

...
...
  "/app/image/{documentId}":
    parameters:
      - in: path
        name: documentId
        schema:
          format: int64
          type: integer
        required: true
        description: id of the document
    get:
      summary: Get ImageFileStream for documentId
      responses:
        '200':
          description: OK
          content:
            application/octet-stream:
              schema: '#/components/schemas/ImageFileStream'
        '403':
          description: Forbidden
        '404':
          description: Not Found
        '500':
          description: Internal Server Error
      description: 'Based on a documentId, return a binary file stream for the asset'
      tags: [ImageFileStream]

...
...
components:
  schemas:
    ImageFileStream:
      type: string
      description: File stream for an image
      title: Image file stream
      format: binary
      readOnly: true


Resulting exception thrown by RESTBuilder: 

Exception in thread "main" java.lang.RuntimeException: Error generating REST API
Error in file "rest-openapi.yaml": null
	at com.liferay.portal.tools.rest.builder.RESTBuilder.main(RESTBuilder.java:126)

This is mentioned as supported within OpenAPI v3.0 - refer to the section Response That Returns a File in the OpenAPI spec.

While the spec indicates that one can just indicate a binary response - I have to incorporate a tag/resource in the RESTBuilder yaml - otherwise no Resource gets built. 

Again - any information on the above would be most helpful.

thumbnail
Javier Gamarra, modified 3 Years ago.

RE: RE: Headless API - Is there a WebServerServlet equivalent?

Expert Posts: 348 Join Date: 2/12/15 Recent Posts

Binary responses are supported but we have some flaws in the implementation (https://issues.liferay.com/browse/LPS-110447). The best way of defining them would be like the Batch API is doing: https://github.com/liferay/liferay-portal/blob/7748a8326979c11a3563eed2da15ad4fd0ef915b/modules/apps/headless/headless-batch-engine/headless-batch-engine-impl/rest-openapi.yaml#L186

That let's you return a Response object that can be anything: a DTO or in this case an output stream:

https://github.com/liferay/liferay-portal/blob/83e8e3c52b30cc8af9ba554700c7e4617bf3d771/modules/apps/headless/headless-batch-engine/headless-batch-engine-impl/src/main/java/com/liferay/headless/batch/engine/internal/resource/v1_0/ExportTaskResourceImpl.java#L80

thumbnail
Christopher Dawson, modified 3 Years ago.

RE: RE: Headless API - Is there a WebServerServlet equivalent?

New Member Posts: 11 Join Date: 2/27/12 Recent Posts

Thanks for the feedback Javier. Appreciate the timely response.

thumbnail
Javier Gamarra, modified 3 Years ago.

RE: Headless API - Is there a WebServerServlet equivalent?

Expert Posts: 348 Join Date: 2/12/15 Recent Posts

Mmm... it's a good question, most use cases getting images from the APIs are for retrieving meta information of *public* images. I guess that your use case is that you want to render private images and you want them to stay that way. So you can not embed them directly in an <img tag...

So we can...

-> Embed them. I would not recomment embedding images in a GET collection request because you can end with a large request (>1MB) that timeouts/get's dropped and chaos occurs. If you are getting images in a small number of requests (0-10) and those images are small (like >200kb) I don't see the problem, the browser would have to do an extra request either way of that similar size. You lose some things like caching the image automatically and some optimizations but I think it's Ok.

-> Use the contentUrl. That was the planned path. But it that image is private we have to pass the token in the request. There is a limitation with basic auth right now that will be removed in the future but OAuth2/tokens is fine.

-> Use adapted Images that are usually public and work with Basic Auth. The path http://localhost:8080/o/adaptive-media/image/12345/Preview-1000x0/AnImage-123.png?t=1538761582000 should work for those...

-> Create an API that returns the image.