You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@sling.apache.org by lancedolan <la...@gmail.com> on 2017/01/27 21:27:20 UTC

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

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.

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

Posted by beaudet <be...@gmail.com>.
Lance, we are trying to do something similar.  We have an enterprise DAM and
would like to extend Adobe AEM 6.2 to enable the native AEM DAM UI widgets
to work with those remote assets in addition to native AEM assets.  We would
also like to enable search of those digital assets via the AEM content
finder and browse the assets via the native AEM components.  Did you have a
similar requirement regarding finding of the assets by content authors and
if so, would you mind sharing your solution for that?

Thanks,

Dave Beaudet
National Gallery of Art, Washington



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

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

Posted by Henry Saginor <hs...@gmail.com>.
Oh you beat to it.:)  I had a similar approach for aggregating page specific JavaScript via a fake resource and was going to provide a skeleton of it. But I am glad you got it to work.

I want to add that Sling could probably benefit from Jersey-like ability to generate web services from simple POJOs. Maybe some day something like that can be implemented on top of Sling Models. :)
I think this is mainly what developers are looking for when they talk about such integration.

> On Jan 31, 2017, at 1:25 PM, lancedolan <la...@gmail.com> wrote:
> 
> Aha! Solved!!!! Here's my solution for posterity.
> 
> While Jersey would have been a preferred, more feature-rich solution, I just
> couldn't get the OSGI-Jersey stuff working.
> 
> The solution: 
> 
> - ResourceProvider listens for all requests to a particular path, and
> returns a false "Resource" object, which doesn't actually exist in the JCR,
> but it does have a resourceType
> 
> - A Servlet registers to render that resourceType.
> 
> Between these two, you've essentially got a Servlet that listens to a all
> requests that fall under a particular Path :)
> 
> Registering a Servlet for a resourceType is pretty elementary, but for
> posterity looking to get this ResourceProvider working in Sling 8, here's
> how I did it. I expect there are better ways, but this is demonstrative:
> 
> 
> /**
> * Created by lancedolan on 1/27/17.
> */
> @Component
> @Service(value=ResourceProvider.class)
> @Properties({
>        @Property(name = ResourceProvider.ROOTS, value = "service/image"),
>        @Property(name = ResourceProvider.OWNS_ROOTS, value = "true")
> })
> public class ImageResourceProvider implements ResourceProvider  {
> 
> //    @Override
>    public Resource getResource(ResourceResolver resourceResolver, String
> path) {
> 
>        AbstractResource abstractResource;
>        abstractResource = new AbstractResource() {
>            @Override
>            public String getResourceType() {
>                return ImageTypeServlet.RESOURCE_TYPE;
>            }
> 
>            @Override
>            public String getResourceSuperType() {
>                return null;
>            }
> 
>            @Override
>            public String getPath() {
>                return path;
>            }
> 
>            @Override
>            public ResourceResolver getResourceResolver() {
>                return resourceResolver;
>            }
> 
>            @Override
>            public ResourceMetadata getResourceMetadata() {
>                return new ResourceMetadata();
>            }
>        };
> 
>        return abstractResource;
>    }
> 
> //    @Override
>    public Resource getResource(ResourceResolver resourceResolver,
> HttpServletRequest httpServletRequest, String path) {
>        return getResource(resourceResolver , path);
>    }
> 
> //    @Override
>    public Iterator<Resource> listChildren(Resource resource) {
>        return null;
>    }
> }
> 
> And then you just create your own servlet, analogous to my ImageTypeServlet
> which contains a static final String RESOURCE_TYPE
> 
> 
> 
> --
> View this message in context: http://apache-sling.73963.n3.nabble.com/How-to-create-Rest-APIs-for-non-JCR-data-in-Sling-8-tp4069947p4070023.html
> Sent from the Sling - Users mailing list archive at Nabble.com.


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

Posted by Bertrand Delacretaz <bd...@apache.org>.
Hi Lance,

On Tue, Jan 31, 2017 at 10:25 PM, lancedolan <la...@gmail.com> wrote:
> Aha! Solved!!!! Here's my solution for posterity....

thanks for sharing!

Note that (and maybe I should have tried that earlier, sorry) you can
also use our planets resource example on Sling 8 by building it as
follows:

svn co -r1660344
https://svn.apache.org/repos/asf/sling/trunk/launchpad/test-services
rm -f $(find src -type f | grep -v Planet)
mvn clean install

...load and start the resulting bundle on Sling 8, it has just the
planets resource provider then

With this the following requests work for me:

curl http://localhost:8080/planets/earth.tidy.2.json

curl http://localhost:8080/planets.tidy.2.json

-Bertrand

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

Posted by lancedolan <la...@gmail.com>.
Aha! Solved!!!! Here's my solution for posterity.

While Jersey would have been a preferred, more feature-rich solution, I just
couldn't get the OSGI-Jersey stuff working.

The solution: 

- ResourceProvider listens for all requests to a particular path, and
returns a false "Resource" object, which doesn't actually exist in the JCR,
but it does have a resourceType

- A Servlet registers to render that resourceType.

Between these two, you've essentially got a Servlet that listens to a all
requests that fall under a particular Path :)

Registering a Servlet for a resourceType is pretty elementary, but for
posterity looking to get this ResourceProvider working in Sling 8, here's
how I did it. I expect there are better ways, but this is demonstrative:


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

//    @Override
    public Resource getResource(ResourceResolver resourceResolver, String
path) {

        AbstractResource abstractResource;
        abstractResource = new AbstractResource() {
            @Override
            public String getResourceType() {
                return ImageTypeServlet.RESOURCE_TYPE;
            }

            @Override
            public String getResourceSuperType() {
                return null;
            }

            @Override
            public String getPath() {
                return path;
            }

            @Override
            public ResourceResolver getResourceResolver() {
                return resourceResolver;
            }

            @Override
            public ResourceMetadata getResourceMetadata() {
                return new ResourceMetadata();
            }
        };

        return abstractResource;
    }

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

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

And then you just create your own servlet, analogous to my ImageTypeServlet
which contains a static final String RESOURCE_TYPE



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

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

Posted by Henry Saginor <hs...@gmail.com>.
I apologize. I think I missed the “serving up large number of virtual resources” part of your requirements.
You can use JCR nodes just to create resources that map to your resource type and still get your data from anywhere.
But if resource path itself needs to be dynamic or it’s difficult to manage JCR nodes for those resources then a better approach would be create a “fake” resource as you are doing.
You may have such a use case. This is probably the part of your requirement that I missed.

BTW I do apologize if I came across like I was questioning your experience. I did not mean it that way at all. I do have a lot of experience with Sling and CQ/AEM as well. :)  

> On Jan 31, 2017, at 12:57 PM, lancedolan <la...@gmail.com> wrote:
> 
> Henry Saginor-2 wrote
>> Hi Lance,
>> 
>> I think a better practice is to register your servlet with a resource type
>> instead of path.
> 
> This requires creating a node per resource. Please see my prior post where I
> disqualify all solutions that involve creating nodes. My entire requirement
> is that I'm creating a service that serves data that isn't in the JCR. I
> truly do appreciate your taking the time out of your day to try to help me,
> though, so I hope you don't feel slighted! :) I have been lead AEM Architect
> on Sling applications that serve millions of users globally and am already
> familiar with the fundamentals of Sling resource and script resolution :) 

> This is just my first time needing to serve up "virtual" resources of very
> large number like this, such that a dynamic-URL service is absolutely the
> only solution.
> 
> Update: I've made progress with the ResourceProvider solution! It seems the
> 403 response I was getting was actually result of my ResourceProvider
> successfully returning SyntheticResource, which Sling then responded with a
> 403 for...  It seems all I need to learn is how to properly instantiate a
> Resource object and return it :)
> 
> It seems I need to learn about this ResourceWrapper class and how to create
> ResourceMetadata....
> 
> 
> 
> --
> View this message in context: http://apache-sling.73963.n3.nabble.com/How-to-create-Rest-APIs-for-non-JCR-data-in-Sling-8-tp4069947p4070022.html
> Sent from the Sling - Users mailing list archive at Nabble.com.


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

Posted by lancedolan <la...@gmail.com>.
Henry Saginor-2 wrote
> Hi Lance,
> 
> I think a better practice is to register your servlet with a resource type
> instead of path.

This requires creating a node per resource. Please see my prior post where I
disqualify all solutions that involve creating nodes. My entire requirement
is that I'm creating a service that serves data that isn't in the JCR. I
truly do appreciate your taking the time out of your day to try to help me,
though, so I hope you don't feel slighted! :) I have been lead AEM Architect
on Sling applications that serve millions of users globally and am already
familiar with the fundamentals of Sling resource and script resolution :)
This is just my first time needing to serve up "virtual" resources of very
large number like this, such that a dynamic-URL service is absolutely the
only solution.

Update: I've made progress with the ResourceProvider solution! It seems the
403 response I was getting was actually result of my ResourceProvider
successfully returning SyntheticResource, which Sling then responded with a
403 for...  It seems all I need to learn is how to properly instantiate a
Resource object and return it :)

It seems I need to learn about this ResourceWrapper class and how to create
ResourceMetadata....



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

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

Posted by Henry Saginor <hs...@gmail.com>.
Hi Lance,

I think a better practice is to register your servlet with a resource type instead of path. For this you can use either sling.servlet.resourceType property or a newer SlingServlet annotation with resourceType property [1].
Then create a JCR note with sling:resourceType property referencing the above resource type. This way you can create resources anywhere in the resource tree and manage ACLs at any level your application requires.

The thing you should understand is that, unlike most traditional web application frameworks, in Sling a URL does not normally point to some script that knows where to find data and how to render it. Instead try to always think of creating a web object (aka resource in Sling ) and sling will automatically know how to render it via sling:resourceType + URL selectors + extension + prefix. 
To me this actually feels more RESTful since a URI addressable resource is the central concept. But, I think, for many developers new to Sling this is the main Sling paradigm they need to understand. After they do things become a lot easier.  

I am planning to provide a simple example as Bertrand asked. I just haven’t had time today. But, I believe if you browse around Sling source repo you should find some existing examples.      

[1] https://sling.apache.org/documentation/the-sling-engine/servlets.html <https://sling.apache.org/documentation/the-sling-engine/servlets.html>

Henry

> On Jan 30, 2017, at 11:37 AM, lancedolan <la...@gmail.com> wrote:
> 
> I guess, even if we use SlingSafeMethodsServlet and request parameter, I
> still have this problem of securing the servlet... I've put a servlet at
> paths = "/myservice/image" , and created a node at /myservice with an ACL
> that denies jcr: all to everyone and anonymous, and yet anonymous can still
> GET /myservice/image. It seems authentication still succeeds, as my Servlet
> can see the user ID on the request, but the authorization via Effective
> Policies isn't happening.
> 
> 
> 
> --
> View this message in context: http://apache-sling.73963.n3.nabble.com/How-to-create-Rest-APIs-for-non-JCR-data-in-Sling-8-tp4069947p4069998.html
> Sent from the Sling - Users mailing list archive at Nabble.com.


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

Posted by lancedolan <la...@gmail.com>.
I guess, even if we use SlingSafeMethodsServlet and request parameter, I
still have this problem of securing the servlet... I've put a servlet at
paths = "/myservice/image" , and created a node at /myservice with an ACL
that denies jcr: all to everyone and anonymous, and yet anonymous can still
GET /myservice/image. It seems authentication still succeeds, as my Servlet
can see the user ID on the request, but the authorization via Effective
Policies isn't happening.



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

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

Posted by lancedolan <la...@gmail.com>.
I'm surprised at all the tech opinions this raised :)

First, there's a couple popular suggestions happening which aren't going in
the right direction, so I'll get that out of the way quick:

1) Any solution that involves me creating a JCR node and binding by resource
type is infeasible. I'm not willing to create a JCR node for each Resource
on the proxied datasource. If I have a million images on S3, and I'm trying
to expose them via /service/image, I'm not willing to create a million nodes
underneath /services/image, nor am I willing to keep that in sync, nor am I
capable of predicting all of the possible images that could be requested in
order to create those nodes. That's a ridiculous amount of work when the
goal is just to make all requests at a dynamic path route to a single
method.

2) Some have also said not to use Sling for this... I appreciate the time
and thought, but that isn't helpful and I must do this in Sling. These
services need access to the JCR for other purposes, and I also want the same
authentication/authorization handlers handling these services as my other
requests to the JCR. There will be a /home principal which is allowed to
access this /service.

If we can't solve this, we'll just use SlingSafeMethodsServlet and use
request parameters instead (ie. /service/image?id=123123 ). This will make
us cringe but we'll bear it.

I'd *really* like to continue down the ResourceProvider path by providing a
path, as shown in my code above. If I can just get past this 403 error, I'm
good! The effective policies of my ResourceProvider at /things should just
inherit "/", which is everyone=jcr:all so it doesn't seem that creating a
node with an ACL on it will help.. I'll continue to play a bit.

As for the Spring suggestions: Thank you, I'll consider this! It seems like
a lot of library to bring in when we'd only use a tiny part of the
functionality.... And anyhow, doesn't Spring just use Jersey under the hood
to provide endpoints?


Bertrand Delacretaz wrote
> We might need to release Sling 9 soon

Yes please :)


Bertrand Delacretaz wrote
> Maybe we just need to flesh out examples like Henry's in actual samples.
> Lance, would that help you?

Isn't his suggestion one involving creating a JCR node for all possible
request paths? So, for /service/{id} which could service a million
unpredictable ids, then I'd need to create a million nodes with names that I
can't predict?



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

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

Posted by Bertrand Delacretaz <bd...@apache.org>.
Hi Lance,

On Fri, Jan 27, 2017 at 10:27 PM, lancedolan <la...@gmail.com> 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

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

Posted by Mike Nimer <mn...@gmail.com>.
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 <la...@gmail.com> 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.

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

Posted by Ben Fortuna <be...@gmail.com>.
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" <ja...@24601.org> 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
> >
>
>

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

Posted by Jason E Bailey <ja...@24601.org>.
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
> 


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

Posted by Ben Fortuna <be...@gmail.com>.
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 <ro...@teeuwen.be> 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 <be...@gmail.com> 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" <hs...@gmail.com>
> 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 <ja...@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...
> >>>>
> >>
> >>
>
>

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

Posted by Roy Teeuwen <ro...@teeuwen.be>.
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 <be...@gmail.com> 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" <hs...@gmail.com> 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 <ja...@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...
>>>> 
>> 
>> 


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

Posted by Ben Fortuna <be...@gmail.com>.
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" <hs...@gmail.com> 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 <ja...@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...
> >>
>
>

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

Posted by Jason E Bailey <ja...@24601.org>.
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 <ja...@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.


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

Posted by Henry Saginor <hs...@gmail.com>.
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 <ja...@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...
>> 


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

Posted by Jason E Bailey <ja...@24601.org>.
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...
> 

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

Posted by Robert Munteanu <ro...@apache.org>.
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.


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

Posted by "Andreas Schaefer Sr." <sc...@me.com>.
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 <la...@gmail.com> 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.


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

Posted by Roy Teeuwen <ro...@teeuwen.be>.
Hey Lance,

If you really want to use jax-rs, have a look at the following:
https://github.com/apache/aries-jax-rs-whiteboard <https://github.com/apache/aries-jax-rs-whiteboard>

Greets,
Roy

> On 27 Jan 2017, at 23:29, lancedolan <la...@gmail.com> 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.


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

Posted by lancedolan <la...@gmail.com>.
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.

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

Posted by Ben Fortuna <be...@gmail.com>.
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 <la...@gmail.com> 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.
>

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

Posted by Roy Teeuwen <ro...@teeuwen.be>.
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 <ol...@gmail.com> 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 <ke...@gmail.com> wrote:
>>> 
>>> On Sat, Jan 28, 2017 at 6:27 AM, lancedolan <la...@gmail.com> 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.
>> 
>> 


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

Posted by olimination <ol...@gmail.com>.
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\u2019t 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\u2019re 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 <ke...@gmail.com> wrote:
>>
>> On Sat, Jan 28, 2017 at 6:27 AM, lancedolan <la...@gmail.com> 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.
> 
> 

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

Posted by Henry Saginor <hs...@gmail.com>.
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 <ke...@gmail.com> wrote:
> 
> On Sat, Jan 28, 2017 at 6:27 AM, lancedolan <la...@gmail.com> 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.


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

Posted by Steven Walters <ke...@gmail.com>.
On Sat, Jan 28, 2017 at 6:27 AM, lancedolan <la...@gmail.com> 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.