Lucee 4.5 & REST API, 404 response?

OK. So, I have a problem with:

REST API on Lucee 4.5, IIS7, Windows 2008R2

Background:

Production Server:

I installed Lucee 4.5 from the official installed, about 2 years ago.
I set up 3 BonCode Handler Mappings for:

*.cfc
*.cfml
*.cfm

My website works fine.

Last week, I decided to set up a REST API instance, using:

this.webAdminPassword = “[my_web_admin_password]”;
RestInitApplication("[system_path_to_wwwroot]/com/api/v1",“api”);

So, my endpoint should be:

https://www.mydomain.com/rest/api/

And an example request URL:

https://www.mydomain.com/rest/api/tokenService/token

TokenService.cfc

<cfscript>

  component rest="true" restPath="tokenService" {
	  
	  remote struct function getToken() httpmethod="get" restPath="/token" produces="application/json"  {
		  return {token: generateSecretKey(request.crptographyalgorithm)};
	  }
	  
  }

</cfscript>

I have done tests to validate that the REST API has been initialised correctly.

On my laptop, I use a developer’s version of ACF11, using port 8500. The REST API works perfectly.

On my production server, whenever I make a REST API request, I get a 404, “Page Not Found” response.

Lucee REST API settings:

In my ‘web.xml’ file found in [system_path_to_C_drive]\Lucee\Tomcat\conf

<servlet>
    <description>Lucee Servlet for RESTful services</description>
    <servlet-name>RestServlet</servlet-name>    
    <servlet-class>lucee.loader.servlet.RestServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>
  
<!-- mapping for Lucee's REST servlet -->
<servlet-mapping>
    <servlet-name>RestServlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

I have both REST API XML blocks uncommented. I have not changed these settings in any way. Essentially, all REST API requests must match /rest/*

web.config:

In my ‘web.config’ file, I have settings for custom pages to handle 404 responses.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
		<httpErrors errorMode="Custom" existingResponse="Replace">
			<remove statusCode="400" subStatusCode="-1" />
			<error statusCode="400" path="https://www.mydomain.com/exception/error/" responseMode="Redirect" />
		    <remove statusCode="403" subStatusCode="-1" />
			<error statusCode="403" path="https://www.mydomain.com/exception/forbidden/" responseMode="Redirect" />
			<remove statusCode="404" subStatusCode="-1" />
			<error statusCode="404" path="https://www.mydomain.com/exception/page-not-found/" responseMode="Redirect" />	
		</httpErrors>
		<httpProtocol>
		 <customHeaders>
		   <add name="Access-Control-Allow-Origin" value="*" />
		 </customHeaders>
		</httpProtocol>
        <rewrite>
            <rules>
                <rule name="Imported Rule 1">
                    <match url="^([a-zA-Z0-9/-]+(index\.cfm)*)$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{DOCUMENT_ROOT}{URL}" matchType="IsDirectory" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="/default{URL}" />
                </rule>
				<rule name="Imported Rule 2">
                    <match url="(.*[^cms|^help]\/teachers)\/(.*)$" ignoreCase="false" />
                    <action type="Rewrite" url="{R:1}/?name={R:2}" />
                </rule>
				<rule name="Imported Rule 3">
                    <match url="(.*[^cms|^help]\/contributors)\/(.*)$" ignoreCase="false" />
                    <action type="Rewrite" url="{R:1}/?name={R:2}" />
                </rule>
				<rule name="Imported Rule 4">
                    <match url="(.*groups)\/(.*)$" ignoreCase="false" />
                    <action type="Rewrite" url="{R:1}/?groups={R:2}" />
                </rule>
				<rule name="Imported Rule 5">
                    <match url="(.*login)\/demo$" ignoreCase="false" />
                    <action type="Rewrite" url="{R:1}/?demomode=true" />
                </rule>
				<rule name="Imported Rule 6">
                    <match url="(.*)\/mobile$" ignoreCase="false" />
                    <action type="Rewrite" url="{R:1}/?mobileuser=true" />
                </rule>
				<rule name="Imported Rule 7">
					<match url="(.*[^cms]\/help\/)(.*[^\.])$" ignoreCase="false" />
                    <action type="Rewrite" url="{R:1}index.cfm/{R:2}" />
				</rule>
				<rule name="Imported Rule 8">
					<match url="(.*\/catalog\/schedule\/)(january\/|february\/|march\/|april\/|may\/|june\/|july\/|august\/|september\/|october\/|november\/|december\/)*([0-9]+)(\/.*)$" ignoreCase="false" />
					<action type="Rewrite" url="{R:1}{R:2}?categoryid={R:3}" />
				</rule>
				<rule name="Imported Rule 9">
					<match url="(.*\/catalog\/category\/)(a\/|b\/|c\/|d\/|e\/|f\/|g\/|h\/|i\/|j\/|k\/|l\/|m\/|n\/|o\/|p\/|q\/|r\/|s\/|t\/|u\/|v\/|w\/|x\/|y\/|z\/)*([0-9]+)(\/.*)$" ignoreCase="false" />
					<action type="Rewrite" url="{R:1}{R:2}?categoryid={R:3}" />
				</rule>
				<rule name="Imported Rule 10">
                    <match url="(.*\/catalog\/schedule\/)(january\/|february\/|march\/|april\/|may\/|june\/|july\/|august\/|september\/|october\/|november\/|december\/)*(.*)$" ignoreCase="false" />
                    <action type="Rewrite" url="{R:1}{R:2}" />
                </rule>
				<rule name="Imported Rule 11">
                    <match url="(.*\/catalog\/category\/)(a\/|b\/|c\/|d\/|e\/|f\/|g\/|h\/|i\/|j\/|k\/|l\/|m\/|n\/|o\/|p\/|q\/|r\/|s\/|t\/|u\/|v\/|w\/|x\/|y\/|z\/)*(.*)$" ignoreCase="false" />
                    <action type="Rewrite" url="{R:1}{R:2}" />
                </rule>
            </rules>
        </rewrite>
		<staticContent>
			<remove fileExtension=".woff" />
			<mimeMap fileExtension=".woff" mimeType="application/octet-stream" />
			<remove fileExtension=".woff2" />
			<mimeMap fileExtension=".woff2" mimeType="application/octet-stream" />
		</staticContent>
    </system.webServer>
	<system.web>
        <customErrors mode="Off" />
		<httpRuntime maxRequestLength="1048576" executionTimeout="10000" />
    </system.web>
</configuration>

Other:

The REST API CFCs, reside in a sub directory of my website root. So, this is not a dedicated REST API server!

QUESTION

Can anyone shed any light, as to why I cannot makes successful REST API requests?

Note, this has been cross posted in the #lucee channel of CFML Slack. I’m following up there and we’ll post the resolution here.

Any ideas ? I’ve the same problem…I’m searching to slack but I didn’t find any
Thanks a lot

David. In the end, I spent nearly a week trying to get this to work, without success. In the end, I decided to use Taffy.io, which is a superb REST API framework for ColdFusion. So easy to set up. Within 10 minutes, I had a working REST API solution:

http://docs.taffy.io/3.2.0

I strongly advise you to go with Taffy, unless you are using the latest version of Lucee/ACF

I agree to stay away from the built in REST in the CF engine, but ColdBox is also a better solution as well. It is more actively developed and professionally supported. You can have a ColdBox MVC REST app up an running in about 2 minutes :slight_smile:

coldbox create app rest
server start
1 Like

Thanks. Good idea. I have latest lucee version but on webservice and some rest I’m experiencing problems to Port some CFC webservice from old cf8 to lucee. And I don’t find many documentation about it.

In this moment I have noticed that Lucee don’t permit to use CFC as soap webservice. I done many test but all CFC I tested work well as soap webservice to coldfusion but not to lucee.
There is a problem on definition of cfcomponent, lucee don’t accept the style document-literal so where I do an invoke, the server don’t reply as a service …
But in this situation , how I can migrate my webservice from coldfusion ?
I spent many hours to test this. Any help?

For example, is there a plug-in I can install to enable the CFC component to work as a soap XML webservice?
Or I have to convert my soap webservice to Rest webservice?

Thanks

David. I have never used SOAP. Sorry…

Ok thanks. I have many soap webservice to migrate.
I have started the rest webservice to lucee now. I found I can use rest webservice to reproduce the soap webservice and now I’m doing some test. Thanks

Seems to work perfectly well out of the box on port 8888 - not sure what’s to avoid, just need to get it through iis… personally we have our own lightweight framework and don’t need taffy or preside (improved coldbox rest)…

If you can’t use vanilla rest out of the box, it should be removed completely from core and rewritten. It should ‘just work’. It should even be more performant than taffy or coldbox without the overhead.

I don’t usually moan :lying_face: but this is really frustrating. Is REST actually broken on Lucee or are there additional steps to init an application that aren’t covered in the video tutorial and documentation?

I have similar problems to above but with Lucee 5.3 on Ubuntu. I have a mature rest app that’s been running on ACF10 for years.

On selling my client the benefits of moving to Lucee and having him now ditch ACF, I’ve installed the app on a new server, created the service mapping in the web admin as per the instructions and I get nothing but an Apache 404. Apart from a few threads in the forum there’s not much documentation to go by - so where do you start?

I agree with @dawesi, if its in the Admin as a feature its not that unreasonable to assume that it should ‘just work’ as it does in ACF, or if Lucee’s REST is different, the necessary caveats and documentation should be available. Maybe you can do things with the ACF implementation that you can’t with Lucee - if so, it needs to be made clear.

If anyones out there reading this who can shed any light, I’m happy to pay for their time to help me sort it out. And if I can sort it out I will happily contribute back what was needed.

Sorry to grumble :pensive:.

is this one of the bugs your seeing?
https://luceeserver.atlassian.net/browse/LDEV-1979

if it’s not in jira, it didn’t happen… acf-compat bugs are considered important, but they need to be filed!

Sadly no, its more fundamental than that - the REST services just don’t run at all in the first place - after setting up the website, adding the mapping, initing the application with restInitApplication() - nada, just the 404 error message

Ah, I’m getting somewhere. I noticed in the Server Overview this info message

The REST Servlet is not configured in your enviroment!

I will add this and report back

Reporting back - got nowhere as the REST servlet and servlet-mapping are in the Tomcat web.xml

Completely stuck now, even the example given in the Lucee REST video doesn’t work https://www.youtube.com/watch?v=R_VnRawOhhc

Does anyone know whether REST works in vhosts - I have seen a comment on YouTube that its only available under the server root?

This is a while back now, but because I am writing my contribution to the ReST section in the Lucee docs these days I found an important point that wasn’t commented here.,

It’s important to know that just installing Lucee with the installer won’t add any reverse proxy for apache2 for the rest services interception. You’ll always get an apache2 404 http error response. The rest connector is there, but set as comment in /etc/apache2/apache2.conf . You need to unset the comment by getting rid of the hash sign # for the rest path and restart apache2. Going to add this stuff soon. Still I need to do some little tests to be be sure I’m not posting non-sense in the docs.

1 Like

I’m adding also this important information here:

During my experiments with REST in a default Lucee installation ( using the installer ) using Apache or IIS in front of Lucee, creating a pure REST application won’t work out of the box. The cause is that even if you have IIS or Apache2 configured properly, mod_cfml will fail to identify these requests as being cfml requests, thus it will consequently fail to create Tomcats web context for new added site/ hostname in IIS/Apache (mod_cfml task is to create the contex settings for sites/virtual hosts added to IIS/Apache in Tomcats configuration for you). Because Tomcat has no configuration set up for those new added sites, Tomcat will deliver it’s own default webroot, causing the impression that Lucee serves only REST applications from Tomcats default server root at Tomcat/webapps/ROOT.

However, this should be easily fixed by adding an empty index.cfm template at the physical location of the webroot of IIS site or apache virtual host. When done, call the index.cfm file through port 80 of your IIIS or apache2 and wait for mod_,cfml to create the context in Tomcat. After that the REST service should be accesible through port 80 of IIS or Apache.

I’m going to add this ASAP in Lucees REST docs, which really needs to be updated soon.

I use Taffy.io for my REST API requirements. It is a Coldfusion REST API framework. Very easy set up. And it just works!

http://taffy.io/

I have never had any success with the Lucee in-built REST API, so I just stopped banging my head against the metaphorical brick wall.

That’s sad @Charles_Robertson. To avoid others banging their heads too, I’ve finally complemented the Lucee docs with a contribution about Lucee Rest Services, which has been merged recently.

The updated section also shows common setup pitfalls, how to add/update webserver connectors and how to trigger mod_cfml to create web-contexts when using fronted webservers like IIS or Apache2.

Credits go to @dawesi for having documented adding boncode connector to IIS in this forum!

If someone finds issues about the docs, please add/edit/update it to the docs or post it to this community site. I did my best, but as we all know: nothing is perfect.

But I hope very much it will help others in future.

Andreas. What you have done is really great. The Docs look good, but my words, the whole REST set up with Lucee, is pretty complicated. I can set up Taffy.io, in five minutes. It’s so much simpler. But, I guess, it is good to give people different choices. I for one will be sticking with Taffy.io, because I cannot see what advantages, going native, would afford?

1 Like