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 <jason.bai...@24601.org> 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 via email to