001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.http.remote;
018
019import static java.lang.annotation.ElementType.*;
020import static java.lang.annotation.RetentionPolicy.*;
021
022import java.lang.annotation.*;
023
024/**
025 * REST proxy method-level <c>multipart/form-data</c> marker annotation.
026 *
027 * <p>
028 * Marks a {@link Remote}-proxy method whose request body is a {@code multipart/form-data} message (RFC 7578)
029 * assembled from the method's {@link org.apache.juneau.http.Part @Part}-annotated parameters &mdash; the
030 * Retrofit <c>@Multipart</c> pattern.  Each {@code @Part} parameter contributes one part (a text field, a
031 * file/stream/byte-array upload, or a serialized bean); the engine adapts those parameters into the streaming
032 * {@link org.apache.juneau.http.entity.MultipartBody} and the {@code multipart/form-data} {@code Content-Type}
033 * (with its generated boundary) is applied automatically.
034 *
035 * <h5 class='figure'>Example:</h5>
036 * <p class='bjava'>
037 *    <ja>@Remote</ja>(path=<js>"/api"</js>)
038 *    <jk>public interface</jk> UploadService {
039 *       <ja>@RemotePost</ja>(<js>"/upload"</js>)
040 *       <ja>@Multipart</ja>
041 *       String upload(
042 *          <ja>@Part</ja>(<js>"title"</js>) String <jv>title</jv>,
043 *          <ja>@Part</ja>(name=<js>"attachment"</js>, contentType=<js>"application/pdf"</js>) File <jv>report</jv>);
044 *    }
045 * </p>
046 *
047 * <h5 class='section'>Body-mode exclusivity:</h5>
048 * <p>
049 * A method is either <i>multipart</i> ({@code @Multipart} + one or more {@link org.apache.juneau.http.Part @Part}
050 * parameters) or <i>single-body</i> ({@link org.apache.juneau.http.Content @Content}), never both.  Declaring both
051 * on the same method &mdash; or declaring {@code @Multipart} with no {@code @Part} parameters, or a {@code @Part}
052 * parameter without {@code @Multipart} &mdash; is rejected at proxy-build time with an
053 * {@link IllegalArgumentException}.
054 *
055 * <h5 class='section'>Notes:</h5><ul>
056 *    <li class='note'>
057 *       <b>Escape hatch (Option B):</b> for advanced cases you can still hand-assemble a
058 *       {@link org.apache.juneau.http.entity.MultipartBody} and pass it as a single
059 *       {@link org.apache.juneau.http.Content @Content} body without {@code @Multipart}; that path is unchanged.
060 *    <li class='note'>
061 *       Honored by the next-generation engine (<c>RestClient.remote(...)</c>) only; the classic engine currently
062 *       ignores this annotation.
063 * </ul>
064 *
065 * <h5 class='section'>See Also:</h5><ul>
066 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/NextGenRestClient">Next-Generation REST Client</a>
067 *    <li class='extlink'><a class="doclink" href="https://www.rfc-editor.org/rfc/rfc7578">RFC 7578 — multipart/form-data</a>
068 * </ul>
069 *
070 * @since 9.2.1
071 */
072@Documented
073@Target(METHOD)
074@Retention(RUNTIME)
075@Inherited
076public @interface Multipart {
077}