How to create Rest APIs for non-JCR data in Sling 8??

classic Classic list List threaded Threaded
29 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

How to create Rest APIs for non-JCR data in Sling 8??

lancedolan
Hi friends,

I've tried routing questions through stackoverflow to cut down my mails to this list. I'm losing lots of time on this one, though, and am stuck.

I need to create APIs which don't represent Sling Resources. Example: /services/images/123123123
that image will exist somewhere else.

Bertrand suggests creating a ResourceProvider, as in the example here [1]. However, that uses the spi package which is not in version 2.9.0 of org.apache.sling.api, and thus, not available to me in Sling 8.

I did find a ResourceProvider interface to implement though, and created this code:

/**
 * Created by lancedolan on 1/27/17.
 */
@Component
@Service(value=ResourceProvider.class)
@Properties({
        @Property(name = ResourceProvider.ROOTS, value = "things"),
        @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
})
public class ImageResourceProvider implements ResourceProvider {

    /** If this provider required a context this would be more elaborate,
     *  but for this simple example we don't need one.
     */
    public static class DoesNotNeedAContext {
    };

    @Override
    public Resource getResource(ResourceResolver resourceResolver, String path) {
        Resource returnResource = new SyntheticResource(resourceResolver, path, "edlio/microservice/image");
        returnResource.getValueMap().put("myProp" , "myValue");
        return returnResource;
    }

    @Override
    public Resource getResource(ResourceResolver resourceResolver, HttpServletRequest httpServletRequest, String path) {
        return getResource(resourceResolver , path);
    }

    @Override
    public Iterator<Resource> listChildren(Resource resource) {
        return null;
    }
}


The result is that I get a 403 response. How do I control the authentication for resources that don't actually exist? The fact that I'm not getting 404 means that my ResourceProvider is at least registering successfully.

Finally, I'd much prefer to use Jersey if possible... Anybody have success getting Jersey to work in Sling 8? I dumped a bunch of time into it and gave up after class not found errors for classes that should be found [2].

The ultimate goal is just to provide a restful API in Sling 8 and the static-path-declaration of SlingSafeMethodsServlet just doesn't cut it.

Thanks a million guys...



[1] https://github.com/apache/sling/blob/trunk/launchpad/test-services/src/main/java/org/apache/sling/launchpad/testservices/resourceprovider/PlanetsResourceProvider.java

[2] http://stackoverflow.com/questions/41901337/how-to-use-jersey-in-sling

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Ben Fortuna-2
Hi Lance,

I would personally recommend that you find a different solution for serving
REST APIs. I also thought it might be good to service an API from Sling, as
it does make JSON a "first class citizen", but then I realised that Sling
is geared towards serving resources from JCR and ultimately you'll be
fighting with the platform to serve an API without all the JCR metadata.

At very least you could try to run Jersey using plain Servlets, but I think
Sling should be left to do what it is meant for.

Other solutions such as Spring Boot or Ratpack are specifically designed
for serving REST APIs, and with Docker it is trivial to support both a
Sling platform for web content and an API back-end on the same server.

One thing about REST APIs I do think Sling is good for is stubbing. You can
easily create example API responses to test your web UI without needing to
run with a back-end (good for UI testing).

regards,
ben


On 28 January 2017 at 08:27, lancedolan <[hidden email]> wrote:

> Hi friends,
>
> I've tried routing questions through stackoverflow to cut down my mails to
> this list. I'm losing lots of time on this one, though, and am stuck.
>
> I need to create APIs which don't represent Sling Resources. Example:
> /services/images/123123123
> that image will exist somewhere else.
>
> Bertrand suggests creating a ResourceProvider, as in the example here [1].
> However, that uses the spi package which is not in version 2.9.0 of
> org.apache.sling.api, and thus, not available to me in Sling 8.
>
> I did find a ResourceProvider interface to implement though, and created
> this code:
>
> /**
>  * Created by lancedolan on 1/27/17.
>  */
> @Component
> @Service(value=ResourceProvider.class)
> @Properties({
>         @Property(name = ResourceProvider.ROOTS, value = "things"),
>         @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
> })
> public class ImageResourceProvider implements ResourceProvider {
>
>     /** If this provider required a context this would be more elaborate,
>      *  but for this simple example we don't need one.
>      */
>     public static class DoesNotNeedAContext {
>     };
>
>     @Override
>     public Resource getResource(ResourceResolver resourceResolver, String
> path) {
>         Resource returnResource = new SyntheticResource(resourceResolver,
> path, "edlio/microservice/image");
>         returnResource.getValueMap().put("myProp" , "myValue");
>         return returnResource;
>     }
>
>     @Override
>     public Resource getResource(ResourceResolver resourceResolver,
> HttpServletRequest httpServletRequest, String path) {
>         return getResource(resourceResolver , path);
>     }
>
>     @Override
>     public Iterator<Resource> listChildren(Resource resource) {
>         return null;
>     }
> }
>
>
> The result is that I get a 403 response. How do I control the
> authentication
> for resources that don't actually exist? The fact that I'm not getting 404
> means that my ResourceProvider is at least registering successfully.
>
> Finally, I'd much prefer to use Jersey if possible... Anybody have success
> getting Jersey to work in Sling 8? I dumped a bunch of time into it and
> gave
> up after class not found errors for classes that should be found [2].
>
> The ultimate goal is just to provide a restful API in Sling 8 and the
> static-path-declaration of SlingSafeMethodsServlet just doesn't cut it.
>
> Thanks a million guys...
>
>
>
> [1]
> https://github.com/apache/sling/blob/trunk/launchpad/
> test-services/src/main/java/org/apache/sling/launchpad/
> testservices/resourceprovider/PlanetsResourceProvider.java
>
> [2] http://stackoverflow.com/questions/41901337/how-to-use-jersey-in-sling
>
>
>
>
>
> --
> View this message in context: http://apache-sling.73963.n3.
> nabble.com/How-to-create-Rest-APIs-for-non-JCR-data-in-
> Sling-8-tp4069947.html
> Sent from the Sling - Users mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

lancedolan
These APIs I'm looking to build are likely to use other OSGI services I've written, and perhaps even write to the JCR for other reasons. Imagine doing a GET /api/images/my-new-image.jpg and the image lives in Amazon S3, but you want to write some audit data into the JCR.

I'm still thinking through the overall solution, and have considered you're suggestion, but I don't want to give up on building APIs inside of OSGI/Sling unless I really need to.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Roy Teeuwen
Hey Lance,

If you really want to use jax-rs, have a look at the following:

Greets,
Roy

On 27 Jan 2017, at 23:29, lancedolan <[hidden email]> wrote:

These APIs I'm looking to build are likely to use other OSGI services I've
written, and perhaps even write to the JCR for other reasons. Imagine doing
a GET /api/images/my-new-image.jpg and the image lives in Amazon S3, but you
want to write some audit data into the JCR.

I'm still thinking through the overall solution, and have considered you're
suggestion, but I don't want to give up on building APIs inside of
OSGI/Sling unless I really need to.



--
View this message in context: http://apache-sling.73963.n3.nabble.com/How-to-create-Rest-APIs-for-non-JCR-data-in-Sling-8-tp4069947p4069949.html
Sent from the Sling - Users mailing list archive at Nabble.com.


signature.asc (817 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Andreas Schaefer
In reply to this post by lancedolan
I never develop for Sling but a few years doing backend on AEM.

So I am wondering if you used the Sling IDE Tooling (Eclipse or our IntelliJ Plugin)
and debugged your code there.

Did you try to use a Servlet that is bound to a Type instead of a Path? This
might do what you want.

Cheers - Andy

> On Jan 27, 2017, at 2:29 PM, lancedolan <[hidden email]> wrote:
>
> These APIs I'm looking to build are likely to use other OSGI services I've
> written, and perhaps even write to the JCR for other reasons. Imagine doing
> a GET /api/images/my-new-image.jpg and the image lives in Amazon S3, but you
> want to write some audit data into the JCR.
>
> I'm still thinking through the overall solution, and have considered you're
> suggestion, but I don't want to give up on building APIs inside of
> OSGI/Sling unless I really need to.
>
>
>
> --
> View this message in context: http://apache-sling.73963.n3.nabble.com/How-to-create-Rest-APIs-for-non-JCR-data-in-Sling-8-tp4069947p4069949.html
> Sent from the Sling - Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Mike Nimer
In reply to this post by lancedolan
Check out http://neba.io/ it should do what you need with Spring
instead of Jersey.

hope this helps
--mike

On Fri, Jan 27, 2017 at 3:27 PM, lancedolan <[hidden email]> wrote:

> Hi friends,
>
> I've tried routing questions through stackoverflow to cut down my mails to
> this list. I'm losing lots of time on this one, though, and am stuck.
>
> I need to create APIs which don't represent Sling Resources. Example:
> /services/images/123123123
> that image will exist somewhere else.
>
> Bertrand suggests creating a ResourceProvider, as in the example here [1].
> However, that uses the spi package which is not in version 2.9.0 of
> org.apache.sling.api, and thus, not available to me in Sling 8.
>
> I did find a ResourceProvider interface to implement though, and created
> this code:
>
> /**
>  * Created by lancedolan on 1/27/17.
>  */
> @Component
> @Service(value=ResourceProvider.class)
> @Properties({
>         @Property(name = ResourceProvider.ROOTS, value = "things"),
>         @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
> })
> public class ImageResourceProvider implements ResourceProvider {
>
>     /** If this provider required a context this would be more elaborate,
>      *  but for this simple example we don't need one.
>      */
>     public static class DoesNotNeedAContext {
>     };
>
>     @Override
>     public Resource getResource(ResourceResolver resourceResolver, String
> path) {
>         Resource returnResource = new SyntheticResource(resourceResolver,
> path, "edlio/microservice/image");
>         returnResource.getValueMap().put("myProp" , "myValue");
>         return returnResource;
>     }
>
>     @Override
>     public Resource getResource(ResourceResolver resourceResolver,
> HttpServletRequest httpServletRequest, String path) {
>         return getResource(resourceResolver , path);
>     }
>
>     @Override
>     public Iterator<Resource> listChildren(Resource resource) {
>         return null;
>     }
> }
>
>
> The result is that I get a 403 response. How do I control the authentication
> for resources that don't actually exist? The fact that I'm not getting 404
> means that my ResourceProvider is at least registering successfully.
>
> Finally, I'd much prefer to use Jersey if possible... Anybody have success
> getting Jersey to work in Sling 8? I dumped a bunch of time into it and gave
> up after class not found errors for classes that should be found [2].
>
> The ultimate goal is just to provide a restful API in Sling 8 and the
> static-path-declaration of SlingSafeMethodsServlet just doesn't cut it.
>
> Thanks a million guys...
>
>
>
> [1]
> https://github.com/apache/sling/blob/trunk/launchpad/test-services/src/main/java/org/apache/sling/launchpad/testservices/resourceprovider/PlanetsResourceProvider.java
>
> [2] http://stackoverflow.com/questions/41901337/how-to-use-jersey-in-sling
>
>
>
>
>
> --
> View this message in context: http://apache-sling.73963.n3.nabble.com/How-to-create-Rest-APIs-for-non-JCR-data-in-Sling-8-tp4069947.html
> Sent from the Sling - Users mailing list archive at Nabble.com.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Steven Walters
In reply to this post by lancedolan
On Sat, Jan 28, 2017 at 6:27 AM, lancedolan <[hidden email]> wrote:

> Hi friends,
>
> I've tried routing questions through stackoverflow to cut down my mails to
> this list. I'm losing lots of time on this one, though, and am stuck.
>
> I need to create APIs which don't represent Sling Resources. Example:
> /services/images/123123123
> that image will exist somewhere else.
>
> Bertrand suggests creating a ResourceProvider, as in the example here [1].
> However, that uses the spi package which is not in version 2.9.0 of
> org.apache.sling.api, and thus, not available to me in Sling 8.
>
> I did find a ResourceProvider interface to implement though, and created
> this code:
>
> /**
>  * Created by lancedolan on 1/27/17.
>  */
> @Component
> @Service(value=ResourceProvider.class)
> @Properties({
>         @Property(name = ResourceProvider.ROOTS, value = "things"),
>         @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
> })
> public class ImageResourceProvider implements ResourceProvider {
>
>     /** If this provider required a context this would be more elaborate,
>      *  but for this simple example we don't need one.
>      */
>     public static class DoesNotNeedAContext {
>     };
>
>     @Override
>     public Resource getResource(ResourceResolver resourceResolver, String
> path) {
>         Resource returnResource = new SyntheticResource(resourceResolver,
> path, "edlio/microservice/image");
>         returnResource.getValueMap().put("myProp" , "myValue");
>         return returnResource;
>     }
>
>     @Override
>     public Resource getResource(ResourceResolver resourceResolver,
> HttpServletRequest httpServletRequest, String path) {
>         return getResource(resourceResolver , path);
>     }
>
>     @Override
>     public Iterator<Resource> listChildren(Resource resource) {
>         return null;
>     }
> }
>
>
> The result is that I get a 403 response. How do I control the authentication
> for resources that don't actually exist? The fact that I'm not getting 404
> means that my ResourceProvider is at least registering successfully.
>
> Finally, I'd much prefer to use Jersey if possible... Anybody have success
> getting Jersey to work in Sling 8? I dumped a bunch of time into it and gave
> up after class not found errors for classes that should be found [2].
>
> The ultimate goal is just to provide a restful API in Sling 8 and the
> static-path-declaration of SlingSafeMethodsServlet just doesn't cut it.
>
> Thanks a million guys...

The Sling paradigm for this is to create resources through the
resource provider,
and then create/register a servlet to respond to the resource type
you're creating (not a static path).

So from your above code, you'd create an additional servlet registered
to the resourceType "edlio/microservice/image" (instead of registered
to a static path) and implement GET inside it.

Without the corresponding servlet, this is most likely being served by
the default GET servlet, which will not particularly understand how to
deal with these resources, thus the errors.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Henry Saginor-2
Can’t you just create sling servlet registered to some resource type?
You can then simply create JCR node(s) mapped to your resource type.
You can also use a SynthaticResource via custom resource provider, which is the track you’re on and what Steven is suggesting.
But I find that in most cases just creating a JCR node is more convenient and you can apply JCR ACLs to it control access if you need it.

> On Jan 27, 2017, at 9:34 PM, Steven Walters <[hidden email]> wrote:
>
> On Sat, Jan 28, 2017 at 6:27 AM, lancedolan <[hidden email]> wrote:
>> Hi friends,
>>
>> I've tried routing questions through stackoverflow to cut down my mails to
>> this list. I'm losing lots of time on this one, though, and am stuck.
>>
>> I need to create APIs which don't represent Sling Resources. Example:
>> /services/images/123123123
>> that image will exist somewhere else.
>>
>> Bertrand suggests creating a ResourceProvider, as in the example here [1].
>> However, that uses the spi package which is not in version 2.9.0 of
>> org.apache.sling.api, and thus, not available to me in Sling 8.
>>
>> I did find a ResourceProvider interface to implement though, and created
>> this code:
>>
>> /**
>> * Created by lancedolan on 1/27/17.
>> */
>> @Component
>> @Service(value=ResourceProvider.class)
>> @Properties({
>>        @Property(name = ResourceProvider.ROOTS, value = "things"),
>>        @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
>> })
>> public class ImageResourceProvider implements ResourceProvider {
>>
>>    /** If this provider required a context this would be more elaborate,
>>     *  but for this simple example we don't need one.
>>     */
>>    public static class DoesNotNeedAContext {
>>    };
>>
>>    @Override
>>    public Resource getResource(ResourceResolver resourceResolver, String
>> path) {
>>        Resource returnResource = new SyntheticResource(resourceResolver,
>> path, "edlio/microservice/image");
>>        returnResource.getValueMap().put("myProp" , "myValue");
>>        return returnResource;
>>    }
>>
>>    @Override
>>    public Resource getResource(ResourceResolver resourceResolver,
>> HttpServletRequest httpServletRequest, String path) {
>>        return getResource(resourceResolver , path);
>>    }
>>
>>    @Override
>>    public Iterator<Resource> listChildren(Resource resource) {
>>        return null;
>>    }
>> }
>>
>>
>> The result is that I get a 403 response. How do I control the authentication
>> for resources that don't actually exist? The fact that I'm not getting 404
>> means that my ResourceProvider is at least registering successfully.
>>
>> Finally, I'd much prefer to use Jersey if possible... Anybody have success
>> getting Jersey to work in Sling 8? I dumped a bunch of time into it and gave
>> up after class not found errors for classes that should be found [2].
>>
>> The ultimate goal is just to provide a restful API in Sling 8 and the
>> static-path-declaration of SlingSafeMethodsServlet just doesn't cut it.
>>
>> Thanks a million guys...
>
> The Sling paradigm for this is to create resources through the
> resource provider,
> and then create/register a servlet to respond to the resource type
> you're creating (not a static path).
>
> So from your above code, you'd create an additional servlet registered
> to the resourceType "edlio/microservice/image" (instead of registered
> to a static path) and implement GET inside it.
>
> Without the corresponding servlet, this is most likely being served by
> the default GET servlet, which will not particularly understand how to
> deal with these resources, thus the errors.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

olimination
Hi Lance,

as Mike already mentioned the "Neba framework" offers you the full
Spring power, meaning you can easily write Spring controllers which then
for example inject your needed OSGi services and you then do whatever
you need to do plus you have access to all the possibilities Spring
offers you.

See doc here: http://neba.io/documentation.html#spring_mvc

Or as far as I know with OSGi R7 there will be support for JAX-RS.

See here: https://adapt.to/2016/en/schedule/osgi-r7.html

cheers,
Oli

On 28.01.2017 07:23, Henry Saginor wrote:

> Can’t you just create sling servlet registered to some resource type?
> You can then simply create JCR node(s) mapped to your resource type.
> You can also use a SynthaticResource via custom resource provider, which is the track you’re on and what Steven is suggesting.
> But I find that in most cases just creating a JCR node is more convenient and you can apply JCR ACLs to it control access if you need it.
>
>> On Jan 27, 2017, at 9:34 PM, Steven Walters <[hidden email]> wrote:
>>
>> On Sat, Jan 28, 2017 at 6:27 AM, lancedolan <[hidden email]> wrote:
>>> Hi friends,
>>>
>>> I've tried routing questions through stackoverflow to cut down my mails to
>>> this list. I'm losing lots of time on this one, though, and am stuck.
>>>
>>> I need to create APIs which don't represent Sling Resources. Example:
>>> /services/images/123123123
>>> that image will exist somewhere else.
>>>
>>> Bertrand suggests creating a ResourceProvider, as in the example here [1].
>>> However, that uses the spi package which is not in version 2.9.0 of
>>> org.apache.sling.api, and thus, not available to me in Sling 8.
>>>
>>> I did find a ResourceProvider interface to implement though, and created
>>> this code:
>>>
>>> /**
>>> * Created by lancedolan on 1/27/17.
>>> */
>>> @Component
>>> @Service(value=ResourceProvider.class)
>>> @Properties({
>>>        @Property(name = ResourceProvider.ROOTS, value = "things"),
>>>        @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
>>> })
>>> public class ImageResourceProvider implements ResourceProvider {
>>>
>>>    /** If this provider required a context this would be more elaborate,
>>>     *  but for this simple example we don't need one.
>>>     */
>>>    public static class DoesNotNeedAContext {
>>>    };
>>>
>>>    @Override
>>>    public Resource getResource(ResourceResolver resourceResolver, String
>>> path) {
>>>        Resource returnResource = new SyntheticResource(resourceResolver,
>>> path, "edlio/microservice/image");
>>>        returnResource.getValueMap().put("myProp" , "myValue");
>>>        return returnResource;
>>>    }
>>>
>>>    @Override
>>>    public Resource getResource(ResourceResolver resourceResolver,
>>> HttpServletRequest httpServletRequest, String path) {
>>>        return getResource(resourceResolver , path);
>>>    }
>>>
>>>    @Override
>>>    public Iterator<Resource> listChildren(Resource resource) {
>>>        return null;
>>>    }
>>> }
>>>
>>>
>>> The result is that I get a 403 response. How do I control the authentication
>>> for resources that don't actually exist? The fact that I'm not getting 404
>>> means that my ResourceProvider is at least registering successfully.
>>>
>>> Finally, I'd much prefer to use Jersey if possible... Anybody have success
>>> getting Jersey to work in Sling 8? I dumped a bunch of time into it and gave
>>> up after class not found errors for classes that should be found [2].
>>>
>>> The ultimate goal is just to provide a restful API in Sling 8 and the
>>> static-path-declaration of SlingSafeMethodsServlet just doesn't cut it.
>>>
>>> Thanks a million guys...
>>
>> The Sling paradigm for this is to create resources through the
>> resource provider,
>> and then create/register a servlet to respond to the resource type
>> you're creating (not a static path).
>>
>> So from your above code, you'd create an additional servlet registered
>> to the resourceType "edlio/microservice/image" (instead of registered
>> to a static path) and implement GET inside it.
>>
>> Without the corresponding servlet, this is most likely being served by
>> the default GET servlet, which will not particularly understand how to
>> deal with these resources, thus the errors.
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Roy Teeuwen
Hey Oli,

Isnt that the whiteboard that I gave?
https://github.com/apache/aries-jax-rs-whiteboard <https://github.com/apache/aries-jax-rs-whiteboard>

Greets
Roy


> On 28 Jan 2017, at 09:43, olimination <[hidden email]> wrote:
>
> Hi Lance,
>
> as Mike already mentioned the "Neba framework" offers you the full
> Spring power, meaning you can easily write Spring controllers which then
> for example inject your needed OSGi services and you then do whatever
> you need to do plus you have access to all the possibilities Spring
> offers you.
>
> See doc here: http://neba.io/documentation.html#spring_mvc
>
> Or as far as I know with OSGi R7 there will be support for JAX-RS.
>
> See here: https://adapt.to/2016/en/schedule/osgi-r7.html
>
> cheers,
> Oli
>
> On 28.01.2017 07:23, Henry Saginor wrote:
>> Can’t you just create sling servlet registered to some resource type?
>> You can then simply create JCR node(s) mapped to your resource type.
>> You can also use a SynthaticResource via custom resource provider, which is the track you’re on and what Steven is suggesting.
>> But I find that in most cases just creating a JCR node is more convenient and you can apply JCR ACLs to it control access if you need it.
>>
>>> On Jan 27, 2017, at 9:34 PM, Steven Walters <[hidden email]> wrote:
>>>
>>> On Sat, Jan 28, 2017 at 6:27 AM, lancedolan <[hidden email]> wrote:
>>>> Hi friends,
>>>>
>>>> I've tried routing questions through stackoverflow to cut down my mails to
>>>> this list. I'm losing lots of time on this one, though, and am stuck.
>>>>
>>>> I need to create APIs which don't represent Sling Resources. Example:
>>>> /services/images/123123123
>>>> that image will exist somewhere else.
>>>>
>>>> Bertrand suggests creating a ResourceProvider, as in the example here [1].
>>>> However, that uses the spi package which is not in version 2.9.0 of
>>>> org.apache.sling.api, and thus, not available to me in Sling 8.
>>>>
>>>> I did find a ResourceProvider interface to implement though, and created
>>>> this code:
>>>>
>>>> /**
>>>> * Created by lancedolan on 1/27/17.
>>>> */
>>>> @Component
>>>> @Service(value=ResourceProvider.class)
>>>> @Properties({
>>>>       @Property(name = ResourceProvider.ROOTS, value = "things"),
>>>>       @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
>>>> })
>>>> public class ImageResourceProvider implements ResourceProvider {
>>>>
>>>>   /** If this provider required a context this would be more elaborate,
>>>>    *  but for this simple example we don't need one.
>>>>    */
>>>>   public static class DoesNotNeedAContext {
>>>>   };
>>>>
>>>>   @Override
>>>>   public Resource getResource(ResourceResolver resourceResolver, String
>>>> path) {
>>>>       Resource returnResource = new SyntheticResource(resourceResolver,
>>>> path, "edlio/microservice/image");
>>>>       returnResource.getValueMap().put("myProp" , "myValue");
>>>>       return returnResource;
>>>>   }
>>>>
>>>>   @Override
>>>>   public Resource getResource(ResourceResolver resourceResolver,
>>>> HttpServletRequest httpServletRequest, String path) {
>>>>       return getResource(resourceResolver , path);
>>>>   }
>>>>
>>>>   @Override
>>>>   public Iterator<Resource> listChildren(Resource resource) {
>>>>       return null;
>>>>   }
>>>> }
>>>>
>>>>
>>>> The result is that I get a 403 response. How do I control the authentication
>>>> for resources that don't actually exist? The fact that I'm not getting 404
>>>> means that my ResourceProvider is at least registering successfully.
>>>>
>>>> Finally, I'd much prefer to use Jersey if possible... Anybody have success
>>>> getting Jersey to work in Sling 8? I dumped a bunch of time into it and gave
>>>> up after class not found errors for classes that should be found [2].
>>>>
>>>> The ultimate goal is just to provide a restful API in Sling 8 and the
>>>> static-path-declaration of SlingSafeMethodsServlet just doesn't cut it.
>>>>
>>>> Thanks a million guys...
>>>
>>> The Sling paradigm for this is to create resources through the
>>> resource provider,
>>> and then create/register a servlet to respond to the resource type
>>> you're creating (not a static path).
>>>
>>> So from your above code, you'd create an additional servlet registered
>>> to the resourceType "edlio/microservice/image" (instead of registered
>>> to a static path) and implement GET inside it.
>>>
>>> Without the corresponding servlet, this is most likely being served by
>>> the default GET servlet, which will not particularly understand how to
>>> deal with these resources, thus the errors.
>>
>>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Jason E Bailey
In reply to this post by lancedolan

Its my understanding that the question on ACL's depends on where it is
inheriting the ACL from. Taking your code as literal, you've declared
that you own everything under /things and it would inherit the ACL of /.
So if you put your ROOT as /content/remote/things You could set JCR ACLs
on /content/remote.

Theoretically I assume that your resource could provide an ACL as the
ACL is just a resource in the tree.

As others suggested using a resource provider in this way may not be the
best solution. As the whole point of Sling is to manage content and
splitting it into different pieces can be awkward.

I'm assuming that you don't need to do POST operations, and that using
Oak with an S3 file storage configuration is out.

If you can tell Sling what's on the remote store, you could just use a
reference to the data. In the same way that in AEM, an image component
doesn't necessarily have the image, rather it can have a pointer to the
image.  So your renderer can just go out and retrieve the image and
return it.

Or, the Sling Resource Merger
https://sling.apache.org/documentation/bundles/resource-merger.html

In this case you can merge your resource provider with a JCR Path. So
that your resource provider provides the remote content while the
associated meta data can be stored in the JCR. Haven't tried this myself
though.









--
Jason

On Fri, Jan 27, 2017, at 04:27 PM, lancedolan wrote:

> Hi friends,
>
> I've tried routing questions through stackoverflow to cut down my mails
> to
> this list. I'm losing lots of time on this one, though, and am stuck.
>
> I need to create APIs which don't represent Sling Resources. Example:
> /services/images/123123123
> that image will exist somewhere else.
>
> Bertrand suggests creating a ResourceProvider, as in the example here
> [1].
> However, that uses the spi package which is not in version 2.9.0 of
> org.apache.sling.api, and thus, not available to me in Sling 8.
>
> I did find a ResourceProvider interface to implement though, and created
> this code:
>
> /**
>  * Created by lancedolan on 1/27/17.
>  */
> @Component
> @Service(value=ResourceProvider.class)
> @Properties({
>         @Property(name = ResourceProvider.ROOTS, value = "things"),
>         @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
> })
> public class ImageResourceProvider implements ResourceProvider {
>
>     /** If this provider required a context this would be more elaborate,
>      *  but for this simple example we don't need one.
>      */
>     public static class DoesNotNeedAContext {
>     };
>
>     @Override
>     public Resource getResource(ResourceResolver resourceResolver, String
> path) {
>         Resource returnResource = new SyntheticResource(resourceResolver,
> path, "edlio/microservice/image");
>         returnResource.getValueMap().put("myProp" , "myValue");
>         return returnResource;
>     }
>
>     @Override
>     public Resource getResource(ResourceResolver resourceResolver,
> HttpServletRequest httpServletRequest, String path) {
>         return getResource(resourceResolver , path);
>     }
>
>     @Override
>     public Iterator<Resource> listChildren(Resource resource) {
>         return null;
>     }
> }
>
>
> The result is that I get a 403 response. How do I control the
> authentication
> for resources that don't actually exist? The fact that I'm not getting
> 404
> means that my ResourceProvider is at least registering successfully.
>
> Finally, I'd much prefer to use Jersey if possible... Anybody have
> success
> getting Jersey to work in Sling 8? I dumped a bunch of time into it and
> gave
> up after class not found errors for classes that should be found [2].
>
> The ultimate goal is just to provide a restful API in Sling 8 and the
> static-path-declaration of SlingSafeMethodsServlet just doesn't cut it.
>
> Thanks a million guys...
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Henry Saginor-2
In my opinion Sling is first and foremost a REST framework specifically designed for this kind of thing. It’s not only to serve JCR content.
The paradigm Steven described earlier in this thread is EXACTLY the way to implement it. In the Sling world the resource IS the RESTful object addressable via a URI. The only thing I can add, as I wrote before, is that it’s not necessary to implement a custom resource provider.
You can simply create JCR nodes/resources to map to your resource type via sling:resourceType. And what your servlet returns is up to you and your requirements. That works in most cases.
You can easily integrate your servlet with existing OSGi service via declarative services and use any framework/library you need internally (provided you can make it available in OSGi container) to integrate with your data where it adds value.
But in my opinion it does not make sense integrating Sling with other framework, such as Spring, which follow different paradigms to do the same things as Sling + Declarative Services. It increases complexity and does not add value.

My advice is don’t shoot yourself in the foot and keep things as simple as possible. Just implement a servlet, integrate with existing service via DS if needed, and format and return the response based on your requirements. Then create a resource (JCR or custom ResourceProvider), map it to your servlet via sling:resourceType. This is how I have always implemented RESTful services in Sling without many limitations. The framework is specifically designed for this.

Henry      
 

> On Jan 28, 2017, at 7:57 AM, Jason E Bailey <[hidden email]> wrote:
>
>
> Its my understanding that the question on ACL's depends on where it is
> inheriting the ACL from. Taking your code as literal, you've declared
> that you own everything under /things and it would inherit the ACL of /.
> So if you put your ROOT as /content/remote/things You could set JCR ACLs
> on /content/remote.
>
> Theoretically I assume that your resource could provide an ACL as the
> ACL is just a resource in the tree.
I am not sure if you can do this since ACLs are at JCR level and are checked via JCR.

>
> As others suggested using a resource provider in this way may not be the
> best solution. As the whole point of Sling is to manage content and
> splitting it into different pieces can be awkward.
>
> I'm assuming that you don't need to do POST operations, and that using
> Oak with an S3 file storage configuration is out.
>
> If you can tell Sling what's on the remote store, you could just use a
> reference to the data. In the same way that in AEM, an image component
> doesn't necessarily have the image, rather it can have a pointer to the
> image.  So your renderer can just go out and retrieve the image and
> return it.
>
> Or, the Sling Resource Merger
> https://sling.apache.org/documentation/bundles/resource-merger.html
>
> In this case you can merge your resource provider with a JCR Path. So
> that your resource provider provides the remote content while the
> associated meta data can be stored in the JCR. Haven't tried this myself
> though.
>
>
>
>
>
>
>
>
>
> --
> Jason
>
> On Fri, Jan 27, 2017, at 04:27 PM, lancedolan wrote:
>> Hi friends,
>>
>> I've tried routing questions through stackoverflow to cut down my mails
>> to
>> this list. I'm losing lots of time on this one, though, and am stuck.
>>
>> I need to create APIs which don't represent Sling Resources. Example:
>> /services/images/123123123
>> that image will exist somewhere else.
>>
>> Bertrand suggests creating a ResourceProvider, as in the example here
>> [1].
>> However, that uses the spi package which is not in version 2.9.0 of
>> org.apache.sling.api, and thus, not available to me in Sling 8.
>>
>> I did find a ResourceProvider interface to implement though, and created
>> this code:
>>
>> /**
>> * Created by lancedolan on 1/27/17.
>> */
>> @Component
>> @Service(value=ResourceProvider.class)
>> @Properties({
>>        @Property(name = ResourceProvider.ROOTS, value = "things"),
>>        @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
>> })
>> public class ImageResourceProvider implements ResourceProvider {
>>
>>    /** If this provider required a context this would be more elaborate,
>>     *  but for this simple example we don't need one.
>>     */
>>    public static class DoesNotNeedAContext {
>>    };
>>
>>    @Override
>>    public Resource getResource(ResourceResolver resourceResolver, String
>> path) {
>>        Resource returnResource = new SyntheticResource(resourceResolver,
>> path, "edlio/microservice/image");
>>        returnResource.getValueMap().put("myProp" , "myValue");
>>        return returnResource;
>>    }
>>
>>    @Override
>>    public Resource getResource(ResourceResolver resourceResolver,
>> HttpServletRequest httpServletRequest, String path) {
>>        return getResource(resourceResolver , path);
>>    }
>>
>>    @Override
>>    public Iterator<Resource> listChildren(Resource resource) {
>>        return null;
>>    }
>> }
>>
>>
>> The result is that I get a 403 response. How do I control the
>> authentication
>> for resources that don't actually exist? The fact that I'm not getting
>> 404
>> means that my ResourceProvider is at least registering successfully.
>>
>> Finally, I'd much prefer to use Jersey if possible... Anybody have
>> success
>> getting Jersey to work in Sling 8? I dumped a bunch of time into it and
>> gave
>> up after class not found errors for classes that should be found [2].
>>
>> The ultimate goal is just to provide a restful API in Sling 8 and the
>> static-path-declaration of SlingSafeMethodsServlet just doesn't cut it.
>>
>> Thanks a million guys...
>>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Ben Fortuna-2
Hi Henry,

I agree with what you say about keeping it simple and using a servlet.
However there are many frameworks and platforms today geared towards making
it easier to implement REST APIs, and I think non-trivial APIs would
probably benefit from using one.

As such, to me an API should live outside the Sling process and use sling
as a data/content source.

Regards,
Ben

On 29 Jan 2017 6:09 AM, "Henry Saginor" <[hidden email]> wrote:

> In my opinion Sling is first and foremost a REST framework specifically
> designed for this kind of thing. It’s not only to serve JCR content.
> The paradigm Steven described earlier in this thread is EXACTLY the way to
> implement it. In the Sling world the resource IS the RESTful object
> addressable via a URI. The only thing I can add, as I wrote before, is that
> it’s not necessary to implement a custom resource provider.
> You can simply create JCR nodes/resources to map to your resource type via
> sling:resourceType. And what your servlet returns is up to you and your
> requirements. That works in most cases.
> You can easily integrate your servlet with existing OSGi service via
> declarative services and use any framework/library you need internally
> (provided you can make it available in OSGi container) to integrate with
> your data where it adds value.
> But in my opinion it does not make sense integrating Sling with other
> framework, such as Spring, which follow different paradigms to do the same
> things as Sling + Declarative Services. It increases complexity and does
> not add value.
>
> My advice is don’t shoot yourself in the foot and keep things as simple as
> possible. Just implement a servlet, integrate with existing service via DS
> if needed, and format and return the response based on your requirements.
> Then create a resource (JCR or custom ResourceProvider), map it to your
> servlet via sling:resourceType. This is how I have always implemented
> RESTful services in Sling without many limitations. The framework is
> specifically designed for this.
>
> Henry
>
> > On Jan 28, 2017, at 7:57 AM, Jason E Bailey <[hidden email]>
> wrote:
> >
> >
> > Its my understanding that the question on ACL's depends on where it is
> > inheriting the ACL from. Taking your code as literal, you've declared
> > that you own everything under /things and it would inherit the ACL of /.
> > So if you put your ROOT as /content/remote/things You could set JCR ACLs
> > on /content/remote.
> >
> > Theoretically I assume that your resource could provide an ACL as the
> > ACL is just a resource in the tree.
> I am not sure if you can do this since ACLs are at JCR level and are
> checked via JCR.
> >
> > As others suggested using a resource provider in this way may not be the
> > best solution. As the whole point of Sling is to manage content and
> > splitting it into different pieces can be awkward.
> >
> > I'm assuming that you don't need to do POST operations, and that using
> > Oak with an S3 file storage configuration is out.
> >
> > If you can tell Sling what's on the remote store, you could just use a
> > reference to the data. In the same way that in AEM, an image component
> > doesn't necessarily have the image, rather it can have a pointer to the
> > image.  So your renderer can just go out and retrieve the image and
> > return it.
> >
> > Or, the Sling Resource Merger
> > https://sling.apache.org/documentation/bundles/resource-merger.html
> >
> > In this case you can merge your resource provider with a JCR Path. So
> > that your resource provider provides the remote content while the
> > associated meta data can be stored in the JCR. Haven't tried this myself
> > though.
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > --
> > Jason
> >
> > On Fri, Jan 27, 2017, at 04:27 PM, lancedolan wrote:
> >> Hi friends,
> >>
> >> I've tried routing questions through stackoverflow to cut down my mails
> >> to
> >> this list. I'm losing lots of time on this one, though, and am stuck.
> >>
> >> I need to create APIs which don't represent Sling Resources. Example:
> >> /services/images/123123123
> >> that image will exist somewhere else.
> >>
> >> Bertrand suggests creating a ResourceProvider, as in the example here
> >> [1].
> >> However, that uses the spi package which is not in version 2.9.0 of
> >> org.apache.sling.api, and thus, not available to me in Sling 8.
> >>
> >> I did find a ResourceProvider interface to implement though, and created
> >> this code:
> >>
> >> /**
> >> * Created by lancedolan on 1/27/17.
> >> */
> >> @Component
> >> @Service(value=ResourceProvider.class)
> >> @Properties({
> >>        @Property(name = ResourceProvider.ROOTS, value = "things"),
> >>        @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
> >> })
> >> public class ImageResourceProvider implements ResourceProvider {
> >>
> >>    /** If this provider required a context this would be more elaborate,
> >>     *  but for this simple example we don't need one.
> >>     */
> >>    public static class DoesNotNeedAContext {
> >>    };
> >>
> >>    @Override
> >>    public Resource getResource(ResourceResolver resourceResolver, String
> >> path) {
> >>        Resource returnResource = new SyntheticResource(
> resourceResolver,
> >> path, "edlio/microservice/image");
> >>        returnResource.getValueMap().put("myProp" , "myValue");
> >>        return returnResource;
> >>    }
> >>
> >>    @Override
> >>    public Resource getResource(ResourceResolver resourceResolver,
> >> HttpServletRequest httpServletRequest, String path) {
> >>        return getResource(resourceResolver , path);
> >>    }
> >>
> >>    @Override
> >>    public Iterator<Resource> listChildren(Resource resource) {
> >>        return null;
> >>    }
> >> }
> >>
> >>
> >> The result is that I get a 403 response. How do I control the
> >> authentication
> >> for resources that don't actually exist? The fact that I'm not getting
> >> 404
> >> means that my ResourceProvider is at least registering successfully.
> >>
> >> Finally, I'd much prefer to use Jersey if possible... Anybody have
> >> success
> >> getting Jersey to work in Sling 8? I dumped a bunch of time into it and
> >> gave
> >> up after class not found errors for classes that should be found [2].
> >>
> >> The ultimate goal is just to provide a restful API in Sling 8 and the
> >> static-path-declaration of SlingSafeMethodsServlet just doesn't cut it.
> >>
> >> Thanks a million guys...
> >>
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Roy Teeuwen
Hey Ben,

I have to argue you on that one though. The short definition of Apache Sling from the main site, definitely look at point 1:

Apache Sling in five bullets points

        • REST based web framework
        • Content-driven, using a JCR content repository
        • Powered by OSGi
        • Scripting inside, multiple languages (JSP, server-side javascript, Scala, etc.)
        • Apache Open Source project

Talking about sling as only data/content is just addressing the JCR / Apache OAK part of Sling, then you can just as well say, drop sling and just use oak to store the data/content

Greets
Roy

> On 28 Jan 2017, at 23:27, Ben Fortuna <[hidden email]> wrote:
>
> Hi Henry,
>
> I agree with what you say about keeping it simple and using a servlet.
> However there are many frameworks and platforms today geared towards making
> it easier to implement REST APIs, and I think non-trivial APIs would
> probably benefit from using one.
>
> As such, to me an API should live outside the Sling process and use sling
> as a data/content source.
>
> Regards,
> Ben
>
> On 29 Jan 2017 6:09 AM, "Henry Saginor" <[hidden email]> wrote:
>
>> In my opinion Sling is first and foremost a REST framework specifically
>> designed for this kind of thing. It’s not only to serve JCR content.
>> The paradigm Steven described earlier in this thread is EXACTLY the way to
>> implement it. In the Sling world the resource IS the RESTful object
>> addressable via a URI. The only thing I can add, as I wrote before, is that
>> it’s not necessary to implement a custom resource provider.
>> You can simply create JCR nodes/resources to map to your resource type via
>> sling:resourceType. And what your servlet returns is up to you and your
>> requirements. That works in most cases.
>> You can easily integrate your servlet with existing OSGi service via
>> declarative services and use any framework/library you need internally
>> (provided you can make it available in OSGi container) to integrate with
>> your data where it adds value.
>> But in my opinion it does not make sense integrating Sling with other
>> framework, such as Spring, which follow different paradigms to do the same
>> things as Sling + Declarative Services. It increases complexity and does
>> not add value.
>>
>> My advice is don’t shoot yourself in the foot and keep things as simple as
>> possible. Just implement a servlet, integrate with existing service via DS
>> if needed, and format and return the response based on your requirements.
>> Then create a resource (JCR or custom ResourceProvider), map it to your
>> servlet via sling:resourceType. This is how I have always implemented
>> RESTful services in Sling without many limitations. The framework is
>> specifically designed for this.
>>
>> Henry
>>
>>> On Jan 28, 2017, at 7:57 AM, Jason E Bailey <[hidden email]>
>> wrote:
>>>
>>>
>>> Its my understanding that the question on ACL's depends on where it is
>>> inheriting the ACL from. Taking your code as literal, you've declared
>>> that you own everything under /things and it would inherit the ACL of /.
>>> So if you put your ROOT as /content/remote/things You could set JCR ACLs
>>> on /content/remote.
>>>
>>> Theoretically I assume that your resource could provide an ACL as the
>>> ACL is just a resource in the tree.
>> I am not sure if you can do this since ACLs are at JCR level and are
>> checked via JCR.
>>>
>>> As others suggested using a resource provider in this way may not be the
>>> best solution. As the whole point of Sling is to manage content and
>>> splitting it into different pieces can be awkward.
>>>
>>> I'm assuming that you don't need to do POST operations, and that using
>>> Oak with an S3 file storage configuration is out.
>>>
>>> If you can tell Sling what's on the remote store, you could just use a
>>> reference to the data. In the same way that in AEM, an image component
>>> doesn't necessarily have the image, rather it can have a pointer to the
>>> image.  So your renderer can just go out and retrieve the image and
>>> return it.
>>>
>>> Or, the Sling Resource Merger
>>> https://sling.apache.org/documentation/bundles/resource-merger.html
>>>
>>> In this case you can merge your resource provider with a JCR Path. So
>>> that your resource provider provides the remote content while the
>>> associated meta data can be stored in the JCR. Haven't tried this myself
>>> though.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> --
>>> Jason
>>>
>>> On Fri, Jan 27, 2017, at 04:27 PM, lancedolan wrote:
>>>> Hi friends,
>>>>
>>>> I've tried routing questions through stackoverflow to cut down my mails
>>>> to
>>>> this list. I'm losing lots of time on this one, though, and am stuck.
>>>>
>>>> I need to create APIs which don't represent Sling Resources. Example:
>>>> /services/images/123123123
>>>> that image will exist somewhere else.
>>>>
>>>> Bertrand suggests creating a ResourceProvider, as in the example here
>>>> [1].
>>>> However, that uses the spi package which is not in version 2.9.0 of
>>>> org.apache.sling.api, and thus, not available to me in Sling 8.
>>>>
>>>> I did find a ResourceProvider interface to implement though, and created
>>>> this code:
>>>>
>>>> /**
>>>> * Created by lancedolan on 1/27/17.
>>>> */
>>>> @Component
>>>> @Service(value=ResourceProvider.class)
>>>> @Properties({
>>>>       @Property(name = ResourceProvider.ROOTS, value = "things"),
>>>>       @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
>>>> })
>>>> public class ImageResourceProvider implements ResourceProvider {
>>>>
>>>>   /** If this provider required a context this would be more elaborate,
>>>>    *  but for this simple example we don't need one.
>>>>    */
>>>>   public static class DoesNotNeedAContext {
>>>>   };
>>>>
>>>>   @Override
>>>>   public Resource getResource(ResourceResolver resourceResolver, String
>>>> path) {
>>>>       Resource returnResource = new SyntheticResource(
>> resourceResolver,
>>>> path, "edlio/microservice/image");
>>>>       returnResource.getValueMap().put("myProp" , "myValue");
>>>>       return returnResource;
>>>>   }
>>>>
>>>>   @Override
>>>>   public Resource getResource(ResourceResolver resourceResolver,
>>>> HttpServletRequest httpServletRequest, String path) {
>>>>       return getResource(resourceResolver , path);
>>>>   }
>>>>
>>>>   @Override
>>>>   public Iterator<Resource> listChildren(Resource resource) {
>>>>       return null;
>>>>   }
>>>> }
>>>>
>>>>
>>>> The result is that I get a 403 response. How do I control the
>>>> authentication
>>>> for resources that don't actually exist? The fact that I'm not getting
>>>> 404
>>>> means that my ResourceProvider is at least registering successfully.
>>>>
>>>> Finally, I'd much prefer to use Jersey if possible... Anybody have
>>>> success
>>>> getting Jersey to work in Sling 8? I dumped a bunch of time into it and
>>>> gave
>>>> up after class not found errors for classes that should be found [2].
>>>>
>>>> The ultimate goal is just to provide a restful API in Sling 8 and the
>>>> static-path-declaration of SlingSafeMethodsServlet just doesn't cut it.
>>>>
>>>> Thanks a million guys...
>>>>
>>
>>


signature.asc (817 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Ben Fortuna-2
Hi Roy,

Yes my reference to data/content was based on the OP stating he'll be
storing data in JCR, so effectively yes he probably could just use a JCR
repo backend.

I'm not totally discounting Sling as an API platform, just that it probably
won't integrate easily with other API frameworks (e.g. JAX-RS, Spring,
etc.). Also if the API is serving more than JCR "resources" (i.e. some form
of data processing) then it will probably need to use servlets. A lot of
maybes I guess. ;-)

regards,
ben


On 29 January 2017 at 09:32, Roy Teeuwen <[hidden email]> wrote:

> Hey Ben,
>
> I have to argue you on that one though. The short definition of Apache
> Sling from the main site, definitely look at point 1:
>
> Apache Sling in five bullets points
>
>         • REST based web framework
>         • Content-driven, using a JCR content repository
>         • Powered by OSGi
>         • Scripting inside, multiple languages (JSP, server-side
> javascript, Scala, etc.)
>         • Apache Open Source project
>
> Talking about sling as only data/content is just addressing the JCR /
> Apache OAK part of Sling, then you can just as well say, drop sling and
> just use oak to store the data/content
>
> Greets
> Roy
>
> > On 28 Jan 2017, at 23:27, Ben Fortuna <[hidden email]> wrote:
> >
> > Hi Henry,
> >
> > I agree with what you say about keeping it simple and using a servlet.
> > However there are many frameworks and platforms today geared towards
> making
> > it easier to implement REST APIs, and I think non-trivial APIs would
> > probably benefit from using one.
> >
> > As such, to me an API should live outside the Sling process and use sling
> > as a data/content source.
> >
> > Regards,
> > Ben
> >
> > On 29 Jan 2017 6:09 AM, "Henry Saginor" <[hidden email]>
> wrote:
> >
> >> In my opinion Sling is first and foremost a REST framework specifically
> >> designed for this kind of thing. It’s not only to serve JCR content.
> >> The paradigm Steven described earlier in this thread is EXACTLY the way
> to
> >> implement it. In the Sling world the resource IS the RESTful object
> >> addressable via a URI. The only thing I can add, as I wrote before, is
> that
> >> it’s not necessary to implement a custom resource provider.
> >> You can simply create JCR nodes/resources to map to your resource type
> via
> >> sling:resourceType. And what your servlet returns is up to you and your
> >> requirements. That works in most cases.
> >> You can easily integrate your servlet with existing OSGi service via
> >> declarative services and use any framework/library you need internally
> >> (provided you can make it available in OSGi container) to integrate with
> >> your data where it adds value.
> >> But in my opinion it does not make sense integrating Sling with other
> >> framework, such as Spring, which follow different paradigms to do the
> same
> >> things as Sling + Declarative Services. It increases complexity and does
> >> not add value.
> >>
> >> My advice is don’t shoot yourself in the foot and keep things as simple
> as
> >> possible. Just implement a servlet, integrate with existing service via
> DS
> >> if needed, and format and return the response based on your
> requirements.
> >> Then create a resource (JCR or custom ResourceProvider), map it to your
> >> servlet via sling:resourceType. This is how I have always implemented
> >> RESTful services in Sling without many limitations. The framework is
> >> specifically designed for this.
> >>
> >> Henry
> >>
> >>> On Jan 28, 2017, at 7:57 AM, Jason E Bailey <[hidden email]>
> >> wrote:
> >>>
> >>>
> >>> Its my understanding that the question on ACL's depends on where it is
> >>> inheriting the ACL from. Taking your code as literal, you've declared
> >>> that you own everything under /things and it would inherit the ACL of
> /.
> >>> So if you put your ROOT as /content/remote/things You could set JCR
> ACLs
> >>> on /content/remote.
> >>>
> >>> Theoretically I assume that your resource could provide an ACL as the
> >>> ACL is just a resource in the tree.
> >> I am not sure if you can do this since ACLs are at JCR level and are
> >> checked via JCR.
> >>>
> >>> As others suggested using a resource provider in this way may not be
> the
> >>> best solution. As the whole point of Sling is to manage content and
> >>> splitting it into different pieces can be awkward.
> >>>
> >>> I'm assuming that you don't need to do POST operations, and that using
> >>> Oak with an S3 file storage configuration is out.
> >>>
> >>> If you can tell Sling what's on the remote store, you could just use a
> >>> reference to the data. In the same way that in AEM, an image component
> >>> doesn't necessarily have the image, rather it can have a pointer to the
> >>> image.  So your renderer can just go out and retrieve the image and
> >>> return it.
> >>>
> >>> Or, the Sling Resource Merger
> >>> https://sling.apache.org/documentation/bundles/resource-merger.html
> >>>
> >>> In this case you can merge your resource provider with a JCR Path. So
> >>> that your resource provider provides the remote content while the
> >>> associated meta data can be stored in the JCR. Haven't tried this
> myself
> >>> though.
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>
> >>> --
> >>> Jason
> >>>
> >>> On Fri, Jan 27, 2017, at 04:27 PM, lancedolan wrote:
> >>>> Hi friends,
> >>>>
> >>>> I've tried routing questions through stackoverflow to cut down my
> mails
> >>>> to
> >>>> this list. I'm losing lots of time on this one, though, and am stuck.
> >>>>
> >>>> I need to create APIs which don't represent Sling Resources. Example:
> >>>> /services/images/123123123
> >>>> that image will exist somewhere else.
> >>>>
> >>>> Bertrand suggests creating a ResourceProvider, as in the example here
> >>>> [1].
> >>>> However, that uses the spi package which is not in version 2.9.0 of
> >>>> org.apache.sling.api, and thus, not available to me in Sling 8.
> >>>>
> >>>> I did find a ResourceProvider interface to implement though, and
> created
> >>>> this code:
> >>>>
> >>>> /**
> >>>> * Created by lancedolan on 1/27/17.
> >>>> */
> >>>> @Component
> >>>> @Service(value=ResourceProvider.class)
> >>>> @Properties({
> >>>>       @Property(name = ResourceProvider.ROOTS, value = "things"),
> >>>>       @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
> >>>> })
> >>>> public class ImageResourceProvider implements ResourceProvider {
> >>>>
> >>>>   /** If this provider required a context this would be more
> elaborate,
> >>>>    *  but for this simple example we don't need one.
> >>>>    */
> >>>>   public static class DoesNotNeedAContext {
> >>>>   };
> >>>>
> >>>>   @Override
> >>>>   public Resource getResource(ResourceResolver resourceResolver,
> String
> >>>> path) {
> >>>>       Resource returnResource = new SyntheticResource(
> >> resourceResolver,
> >>>> path, "edlio/microservice/image");
> >>>>       returnResource.getValueMap().put("myProp" , "myValue");
> >>>>       return returnResource;
> >>>>   }
> >>>>
> >>>>   @Override
> >>>>   public Resource getResource(ResourceResolver resourceResolver,
> >>>> HttpServletRequest httpServletRequest, String path) {
> >>>>       return getResource(resourceResolver , path);
> >>>>   }
> >>>>
> >>>>   @Override
> >>>>   public Iterator<Resource> listChildren(Resource resource) {
> >>>>       return null;
> >>>>   }
> >>>> }
> >>>>
> >>>>
> >>>> The result is that I get a 403 response. How do I control the
> >>>> authentication
> >>>> for resources that don't actually exist? The fact that I'm not getting
> >>>> 404
> >>>> means that my ResourceProvider is at least registering successfully.
> >>>>
> >>>> Finally, I'd much prefer to use Jersey if possible... Anybody have
> >>>> success
> >>>> getting Jersey to work in Sling 8? I dumped a bunch of time into it
> and
> >>>> gave
> >>>> up after class not found errors for classes that should be found [2].
> >>>>
> >>>> The ultimate goal is just to provide a restful API in Sling 8 and the
> >>>> static-path-declaration of SlingSafeMethodsServlet just doesn't cut
> it.
> >>>>
> >>>> Thanks a million guys...
> >>>>
> >>
> >>
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Jason E Bailey
In reply to this post by Henry Saginor-2

In general I agree with you, that's the simplest

OP had a dual need. which is storing information about the asset in the
JCR at the same time, which I don't see how your solution handles.

--
Jason

On Sat, Jan 28, 2017, at 02:08 PM, Henry Saginor wrote:

> In my opinion Sling is first and foremost a REST framework specifically
> designed for this kind of thing. It’s not only to serve JCR content.
> The paradigm Steven described earlier in this thread is EXACTLY the way
> to implement it. In the Sling world the resource IS the RESTful object
> addressable via a URI. The only thing I can add, as I wrote before, is
> that it’s not necessary to implement a custom resource provider.
> You can simply create JCR nodes/resources to map to your resource type
> via sling:resourceType. And what your servlet returns is up to you and
> your requirements. That works in most cases.
> You can easily integrate your servlet with existing OSGi service via
> declarative services and use any framework/library you need internally
> (provided you can make it available in OSGi container) to integrate with
> your data where it adds value.
> But in my opinion it does not make sense integrating Sling with other
> framework, such as Spring, which follow different paradigms to do the
> same things as Sling + Declarative Services. It increases complexity and
> does not add value.
>
> My advice is don’t shoot yourself in the foot and keep things as simple
> as possible. Just implement a servlet, integrate with existing service
> via DS if needed, and format and return the response based on your
> requirements. Then create a resource (JCR or custom ResourceProvider),
> map it to your servlet via sling:resourceType. This is how I have always
> implemented RESTful services in Sling without many limitations. The
> framework is specifically designed for this.
>
> Henry      
>  
> > On Jan 28, 2017, at 7:57 AM, Jason E Bailey <[hidden email]> wrote:
> >
> >
> > Its my understanding that the question on ACL's depends on where it is
> > inheriting the ACL from. Taking your code as literal, you've declared
> > that you own everything under /things and it would inherit the ACL of /.
> > So if you put your ROOT as /content/remote/things You could set JCR ACLs
> > on /content/remote.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Jason E Bailey
In reply to this post by Ben Fortuna-2
I'm not sure how to correctly convey my confusion over your statement :)
There may be some bias here, since I've been doing this for a while, but
this is an incredibly easy platform for REST and I haven't ran across
another that gives me the same flexibility.

--
Jason

On Sat, Jan 28, 2017, at 05:27 PM, Ben Fortuna wrote:

> Hi Henry,
>
> I agree with what you say about keeping it simple and using a servlet.
> However there are many frameworks and platforms today geared towards
> making
> it easier to implement REST APIs, and I think non-trivial APIs would
> probably benefit from using one.
>
> As such, to me an API should live outside the Sling process and use sling
> as a data/content source.
>
> Regards,
> Ben
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Ben Fortuna-2
Hi Jason,

Possibly I approached it from the wrong angle in my assessment, happy to
hear it's been working for you and others. I may try again for APIs in
future.

That aside, after using sling for serving web content I can't recommend it
enough. For me it certainly puts the fun back in web development.

Regards,
Ben

On 30 Jan 2017 6:32 AM, "Jason E Bailey" <[hidden email]> wrote:

> I'm not sure how to correctly convey my confusion over your statement :)
> There may be some bias here, since I've been doing this for a while, but
> this is an incredibly easy platform for REST and I haven't ran across
> another that gives me the same flexibility.
>
> --
> Jason
>
> On Sat, Jan 28, 2017, at 05:27 PM, Ben Fortuna wrote:
> > Hi Henry,
> >
> > I agree with what you say about keeping it simple and using a servlet.
> > However there are many frameworks and platforms today geared towards
> > making
> > it easier to implement REST APIs, and I think non-trivial APIs would
> > probably benefit from using one.
> >
> > As such, to me an API should live outside the Sling process and use sling
> > as a data/content source.
> >
> > Regards,
> > Ben
> >
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Robert Munteanu-2
In reply to this post by lancedolan
Hi,

On Fri, 2017-01-27 at 14:27 -0700, lancedolan wrote:

> Hi friends,
>
> I've tried routing questions through stackoverflow to cut down my
> mails to
> this list. I'm losing lots of time on this one, though, and am stuck.
>
> I need to create APIs which don't represent Sling Resources. Example:
> /services/images/123123123
> that image will exist somewhere else.
>
> Bertrand suggests creating a ResourceProvider, as in the example here
> [1].
> However, that uses the spi package which is not in version 2.9.0 of
> org.apache.sling.api, and thus, not available to me in Sling 8.

You can always look at how that ResourceProvider was before moving to
the new ResourceProvider SPI [3],[4]
 
(snip)

> The result is that I get a 403 response. How do I control the
> authentication
> for resources that don't actually exist? The fact that I'm not
> getting 404
> means that my ResourceProvider is at least registering successfully. 

I would check exactly what is going on using the 'Recent Requests'
WebConsole page. IIRC ResourceProviders do not provide authentication
by default.


> Finally, I'd much prefer to use Jersey if possible... Anybody have
> success
> getting Jersey to work in Sling 8? I dumped a bunch of time into it
> and gave
> up after class not found errors for classes that should be found [2].

I would suggest that you stick with the ResourceProvider for now. Yes,
it might not be familiar like Jersey, but it fits in really nicely with
Sling. And BTW, JCR is exposed to Sling via a ResourceProvider, so you
can really get creative with these APIs :-)

Robert

>
> The ultimate goal is just to provide a restful API in Sling 8 and the
> static-path-declaration of SlingSafeMethodsServlet just doesn't cut
> it.
>
> Thanks a million guys...


[3]: https://github.com/apache/sling/blob/30cadbca86c46e1460e19d045ce7d
6f0d475a778/launchpad/test-
services/src/main/java/org/apache/sling/launchpad/testservices/resource
provider/PlanetsResourceProvider.java
[4]: https://github.com/apache/sling/blob/30cadbca86c46e1460e19d045ce7d
6f0d475a778/launchpad/test-
services/src/main/java/org/apache/sling/launchpad/testservices/resource
provider/PlanetResource.java

>
>
>
> [1]
> https://github.com/apache/sling/blob/trunk/launchpad/test-services/sr
> c/main/java/org/apache/sling/launchpad/testservices/resourceprovider/
> PlanetsResourceProvider.java
>
> [2] http://stackoverflow.com/questions/41901337/how-to-use-jersey-in-
> sling
>
>
>
>
>
> --
> View this message in context: http://apache-sling.73963.n3.nabble.com
> /How-to-create-Rest-APIs-for-non-JCR-data-in-Sling-8-tp4069947.html
> Sent from the Sling - Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to create Rest APIs for non-JCR data in Sling 8??

Bertrand Delacretaz
In reply to this post by lancedolan
Hi Lance,

On Fri, Jan 27, 2017 at 10:27 PM, lancedolan <[hidden email]> wrote:
> ...Bertrand suggests creating a ResourceProvider, as in the example here [1].
> However, that uses the spi package which is not in version 2.9.0 of
> org.apache.sling.api, and thus, not available to me in Sling 8....

We might need to release Sling 9 soon, in general that's "only" a
question of getting all tests to run with the specific list of bundles
that we're releasing.

> ...The result is that I get a 403 response. How do I control the authentication
> for resources that don't actually exist?...

As Henry indicates, if you can back part of your resource provider
with JCR nodes that should help.

> ...Finally, I'd much prefer to use Jersey if possible...

That's certainly doable but IMO mixing models like this adds
complexity without adding much value.

Maybe we just need to flesh out examples like Henry's in actual samples.

Lance, would that help you?

Henry, could you turn your example into code, or at least into a
skeleton that I could translate into a complete sample?

-Bertrand
12
Loading...